Re: RFC: %ebp-based backtrace patch

Mark Kettenis
2009-07-06T21:57:43Z

> Date: Mon, 6 Jul 2009 14:33:16 -0400
> From: Daniel Jacobowitz <drow@false.org>
>
> A number of Linux distributions are carrying the attached patch from
> Michael Matz. Frankly, I don't understand i386 frame layout issues
> well enough to approve this; I'm posting this in hopes of starting a
> discussion between Mark Kettenis and Michael Matz. The patch
> does seem to help in practice.
>
> I took a 32-bit Debian system, with minimal packages installed, and
> ran bash inside GDB. I interrupted it while sitting at a prompt.
> Results without the patch:
>
> #0 0xf7fdf430 in __kernel_vsyscall ()
> #1 0xf7f0ce93 in __read_nocancel () from /lib/i686/cmov/libc.so.6
> #2 0x080cfca6 in rl_getc ()
> #3 0x080d0103 in rl_read_key ()
> #4 0x080be7d7 in readline_internal_char ()
> #5 0x080bebc5 in readline ()
> #6 0x080689d1 in ?? ()
> #7 0x081b7808 in ?? ()
> #8 0x080942c0 in ?? ()
> #9 0xffffc5d8 in ?? ()
> #10 0x08080e26 in notify_and_cleanup ()
> #11 0x0806422b in ?? ()
> #12 0x00000000 in ?? ()
>
> With:
>
> #0 0xf7fdf430 in __kernel_vsyscall ()
> #1 0xf7f0ce93 in __read_nocancel () from /lib/i686/cmov/libc.so.6
> #2 0x080cfca6 in rl_getc ()
> #3 0x080d0103 in rl_read_key ()
> #4 0x080be7d7 in readline_internal_char ()
> #5 0x080bebc5 in readline ()
> #6 0x080689d1 in ?? ()
> #7 0x0806422b in ?? ()
> #8 0x08065492 in ?? ()
> #9 0x08068f57 in yyparse ()
> #10 0x08061c98 in parse_command ()
> #11 0x08061d7f in read_command ()
> #12 0x08061fc3 in reader_loop ()
> #13 0x08061ae9 in main ()
>
> Michael's explanation of the patch is over here:
>
> https://bugzilla.novell.com/show_bug.cgi?id=390722#c25
>
> My understanding is that this only affects frames we can't find a
> symbol for. Instead of assuming the frame starts at %esp - 4 (since
> sp_offset is initialized to -4 and then not updated if we did not find
> a symbol to analyze), assume that it uses and saved %ebp. We have no
> reliable information at this point and the new heuristic seems to be
> right more often.
>
> Mark, could you comment on this patch?

Makes sense to me. If we have no clue where we are anymore, taking
the gamble that %ebp is a valid frame pointer probably has better odds
than that %esp points to a valid frame. This will need a comment
though. I'll take care of that.

There is one potential problem though. IIRC early versions of the
vsyscall DSO did not have embedded debug information. This will
probably make backtraces from interrupted system calls on systems with
those kernels fail miserably. Not sure if that's something we really
care about though.

> Daniel Jacobowitz
> CodeSourcery
>
> 2009-07-06 Michael Matz <matz@suse.de>
>
> * i386-tdep.c (i386_frame_cache): Assume anonymous functions use
> a frame pointer.
>
> ---
> gdb/i386-tdep.c | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
>
> Index: gdb-6.8.50.20090628/gdb/i386-tdep.c
> ===================================================================
> --- gdb-6.8.50.20090628.orig/gdb/i386-tdep.c 2009-07-05 20:38:47.000000000 -0400
> +++ gdb-6.8.50.20090628/gdb/i386-tdep.c 2009-07-05 20:39:17.000000000 -0400
> @@ -1377,11 +1377,13 @@ i386_frame_cache (struct frame_info *thi
> /* This will be added back below. */
> cache->saved_regs[I386_EIP_REGNUM] -= cache->base;
> }
> - else
> + else if (cache->pc)
> {
> get_frame_register (this_frame, I386_ESP_REGNUM, buf);
> cache->base = extract_unsigned_integer (buf, 4) + cache->sp_offset;
> }
> + else
> + cache->saved_regs[I386_EBP_REGNUM] = 0;
> }
>
> /* Now that we have the base address for the stack frame we can
>