This is the mail archive of the gdb@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Further cache generating if PC is 0?


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.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]