Mirror of the gdb mailing list
 help / color / mirror / Atom feed
* Further cache generating if PC is 0?
@ 2005-06-23 17:06 Corinna Vinschen
  2005-06-23 18:51 ` Jason Molenda
  0 siblings, 1 reply; 5+ messages in thread
From: Corinna Vinschen @ 2005-06-23 17:06 UTC (permalink / raw)
  To: gdb

I don't know if the subject is clear enough, but here we go.

While debugging, I came across the following situation.  It happened
on i686-pc-linux-gnu, but it's not exactly an ix86 problem.  The idea
is, how does a backtrace look like, if symbol information is missing?
For that purpose, just start any application using share libs and
disallow loading solib symbols:

(gdb) set auto-solib-add no
(gdb) set backtrace past-main
(gdb) br main
Breakpoint 1 at 0x8048465: file x.c, line 82.
(gdb) r
Starting program: /home/corinna/useless-test-app

Breakpoint 1, main (argc=1, argv=0xffffbf54) at x.c:82
82        func_1 (1);
(gdb) bt
#0  main (argc=1, argv=0xffffbf54) at x.c:82
#1  0x55595b10 in ?? () from /lib/tls/libc.so.6
#2  0x00000001 in ?? ()
#3  0xffffbf54 in ?? ()
#4  0xffffbf5c in ?? ()
#5  0x5556cdf8 in ?? ()
#6  0x55692ff4 in ?? () from /lib/tls/libc.so.6
#7  0x5556bcc0 in ?? () from /lib/ld-linux.so.2
#8  0x08048480 in main ()
#9  0x080482c1 in _start () at start.S:119
(gdb) 

Oh well, that doesn't look good.  Now, how *should* it look like:

(gdb) sharedlibrary c
Loaded symbols for /lib/tls/libc.so.6
(gdb) bt
#0  main (argc=1, argv=0xffffbf54) at x.c:82
#1  0x55595b10 in __libc_start_main () from /lib/tls/libc.so.6
#2  0x080482c1 in _start () at start.S:119
(gdb)

So the question was, why does the backtrace look so broken when the
symbol information is missing?  It turned out that this is a result
of not being able to retrieve the function start address in the
i386_frame_cache function.  Many (most?) target_frame_cache function
are doing pretty much the same, just differing in details.  Generally,
they do something like this:

  [...]

  cache->base = frame_unwind_register_unsigned (next_frame, FP_regnum);
  if (cache->base == 0)
    return cache;

  cache->pc = frame_func_unwind (next_frame);
  if (cache->pc != 0)
    analyze_prologue ();

  if (we_dont_know_the_frame_layout || frameless_function)
    cache->base = frame_unwind_register_unsigned (next_frame, SP_regnum)
                + some_offset;

  cache->saved_sp = cache->base + some_other_offset;

  [...]

What goes wrong in the above example is that frame_func_unwind returns 0.
There's no PC to retrieve since no information about the shared library is
given due to switching off auto-solib-add.  Since we don't have a function
address, we can't analyze the prologue.  Since the prologue analyzis
determines our knowledge about the frame layout, but it hasn't been called,
we don't trust the value of the unwinded frame pointer.

Ok, so we unwind the stack pointer and what happens at that point is a
pretty hopeless guess.  The guess is that the function is frameless and
has either no local variables or we're still in the prologue.

So the obvious question is this:

If frame_func_unwind returns 0, isn't proceeding useless and shouldn't the
frame_cache function return 0 in cache->base and return?

Perhaps together with a warning message that the backtrace would become
unreliable if we proceed?


Corinna

-- 
Corinna Vinschen
Cygwin Project Co-Leader
Red Hat, Inc.


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Further cache generating if PC is 0?
  2005-06-23 17:06 Further cache generating if PC is 0? Corinna Vinschen
@ 2005-06-23 18:51 ` Jason Molenda
  2005-06-23 21:13   ` Mark Kettenis
  0 siblings, 1 reply; 5+ messages in thread
From: Jason Molenda @ 2005-06-23 18:51 UTC (permalink / raw)
  To: gdb

Hi Corinna,


On Jun 23, 2005, at 10:06 AM, Corinna Vinschen wrote:

> Ok, so we unwind the stack pointer and what happens at that point is a
> pretty hopeless guess.  The guess is that the function is frameless  
> and
> has either no local variables or we're still in the prologue.

No, if we follow the convention of setting up a frame pointer and  
saving it on function entry (i.e. we're not debugging -fomit-frame- 
pointer code in gcc's terminology), we can do better.  If the  
function we're examining is potentially frameless, then we're reduced  
to guessing.  But if the function we're examining MUST have set up a  
frame, we should assume it did so and continue up the stack.

cf http://sources.redhat.com/ml/gdb-patches/2005-06/msg00060.html


Jason


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Further cache generating if PC is 0?
  2005-06-23 18:51 ` Jason Molenda
@ 2005-06-23 21:13   ` Mark Kettenis
  2005-06-23 21:28     ` Jason Molenda
  0 siblings, 1 reply; 5+ messages in thread
From: Mark Kettenis @ 2005-06-23 21:13 UTC (permalink / raw)
  To: jmolenda; +Cc: gdb

   From: Jason Molenda <jmolenda@apple.com>
   Date: Thu, 23 Jun 2005 11:50:53 -0700

   Hi Corinna,

   On Jun 23, 2005, at 10:06 AM, Corinna Vinschen wrote:

   > Ok, so we unwind the stack pointer and what happens at that point is a
   > pretty hopeless guess.  The guess is that the function is frameless  
   > and
   > has either no local variables or we're still in the prologue.

   No, if we follow the convention of setting up a frame pointer and  
   saving it on function entry (i.e. we're not debugging -fomit-frame- 
   pointer code in gcc's terminology), we can do better.  If the  
   function we're examining is potentially frameless, then we're reduced  
   to guessing.  But if the function we're examining MUST have set up a  
   frame, we should assume it did so and continue up the stack.

   cf http://sources.redhat.com/ml/gdb-patches/2005-06/msg00060.html

Well, I still seem to remember that at one moment in time, around the
time the i386 was converted to using the new frame unwinding code,
there was a fairly common case on Linux systems where the assumption
that there MUST be a frame didn't hold.

I hope to be looking into Jason's patch this weekend, but in any case,
it'll need thorough testing on many systems and with different
compilers.  Only looking at the latest Fedora Core defenitely will not
do.

Mark


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Further cache generating if PC is 0?
  2005-06-23 21:13   ` Mark Kettenis
@ 2005-06-23 21:28     ` Jason Molenda
  2005-06-24  8:07       ` Corinna Vinschen
  0 siblings, 1 reply; 5+ messages in thread
From: Jason Molenda @ 2005-06-23 21:28 UTC (permalink / raw)
  To: Mark Kettenis; +Cc: gdb


On Jun 23, 2005, at 2:13 PM, Mark Kettenis wrote:

>    cf http://sources.redhat.com/ml/gdb-patches/2005-06/msg00060.html
>
> Well, I still seem to remember that at one moment in time, around the
> time the i386 was converted to using the new frame unwinding code,
> there was a fairly common case on Linux systems where the assumption
> that there MUST be a frame didn't hold.

With my patch, if a function could be potentially frameless and we  
can't parse the prologue or we don't know where the function starts,  
I assume it's frameless.  If the function must have set up a frame, I  
assume it set up a frame using the standard save-the-caller's-ebp idiom.

It's entirely reasonable to argue that my assumptions are incorrect.   
But if -fomit-frame-pointer code exists on the stack, *no*  
assumptions are correct.  The current code isn't correct, my code  
isn't correct.  The only correct thing to do is abort the stack  
backtrace and insist that gdb can't continue.

> I hope to be looking into Jason's patch this weekend, but in any case,
> it'll need thorough testing on many systems and with different
> compilers.  Only looking at the latest Fedora Core defenitely will not
> do.

Thanks Mark -- no rush, I'm not going away or going to lose  
interest. :-)

As far as testing on other systems, it's working GREAT on MacOS X for  
Intel. :)

Jason


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Further cache generating if PC is 0?
  2005-06-23 21:28     ` Jason Molenda
@ 2005-06-24  8:07       ` Corinna Vinschen
  0 siblings, 0 replies; 5+ messages in thread
From: Corinna Vinschen @ 2005-06-24  8:07 UTC (permalink / raw)
  To: gdb

On Jun 23 14:27, Jason Molenda wrote:
> 
> On Jun 23, 2005, at 2:13 PM, Mark Kettenis wrote:
> 
> >   cf http://sources.redhat.com/ml/gdb-patches/2005-06/msg00060.html
> >
> >Well, I still seem to remember that at one moment in time, around the
> >time the i386 was converted to using the new frame unwinding code,
> >there was a fairly common case on Linux systems where the assumption
> >that there MUST be a frame didn't hold.
> 
> With my patch, if a function could be potentially frameless and we  
> can't parse the prologue or we don't know where the function starts,  
> I assume it's frameless.  If the function must have set up a frame, I  
> assume it set up a frame using the standard save-the-caller's-ebp idiom.
> 
> It's entirely reasonable to argue that my assumptions are incorrect.   
> But if -fomit-frame-pointer code exists on the stack, *no*  
> assumptions are correct.  The current code isn't correct, my code  
> isn't correct.  The only correct thing to do is abort the stack  
> backtrace and insist that gdb can't continue.

That's basically what I was asking.  As long as the current code
doesn't undergo a major rewrite as mentioned in the above thread,
I'd say that something as

  cache->pc = frame_func_unwind (next_frame);
  if (!cache->pc)
    {
      cache->base = 0;
      return cache;
    }

would be more correct.  However, the above thread implies that it's
too late to worry about it ;-)


Corinna

-- 
Corinna Vinschen
Cygwin Project Co-Leader
Red Hat, Inc.


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2005-06-24  8:07 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-06-23 17:06 Further cache generating if PC is 0? Corinna Vinschen
2005-06-23 18:51 ` Jason Molenda
2005-06-23 21:13   ` Mark Kettenis
2005-06-23 21:28     ` Jason Molenda
2005-06-24  8:07       ` Corinna Vinschen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox