Mark Kettenis writes: > > Jan Kratochvil writes: > > > > > currently (on x86_64) the gdb backtrace does not properly stop at > > > the outermost frame: > > > > > > #3 0x00000036ddb0610a in start_thread () from > > /lib64/tls/libpthread.so.0 > > > #4 0x00000036dd0c68c3 in clone () from /lib64/tls/libc.so.6 > > > #5 0x0000000000000000 in ?? () > > > > > > Currently it relies only on clearing %rbp (0x0000000000000000 above is > > > unrelated to it, it got read from uninitialized memory). > > > > That's how it's defined to work: %rbp is zero. > > > > > http://sourceware.org/ml/gdb/2004-08/msg00060.html suggests frame > > > pointer 0x0 should be enough for a debugger not finding CFI to stop > > > unwinding, still it is a heuristic. > > > > Not by my understanding it isn't. It's set up by the runtime system, > > and 0 (i.e. NULL on x86-64) marks the end of the stack. Officially. > > > > See page 28, AMD64 ABI Draft 0.98 \u2013 September 27, 2006 -- 9:24. > > Unfortunately whoever wrote that down didn't think it through. In > Figure 3.4 on page 20, %rbp is listed as "callee-saved register; > optionally used as frame pointer". So %rbp can be used for anything, as > long as you save its contents and restore it before you return.
Null-terminating the call stack is too well-established practice to be changed now. In practice, %ebp either points to a call frame -- not necessarily the most recent one -- or is null. I don't think that having an optional frame pointer mees you can use %ebp for anything random at all, but we need to make a clarification request of the ABI. > Since it may be used for anything, it may contain 0 at any point in > the middle of the call stack. > So it is unusable as a stack trace termination condition. The only > viable option is explicitly marking it as such in the CFI. > > Initializing %rbp to 0 in the outermost frame is sort of pointless > on amd64. The right way to fix the ABI is to specify that %ebp mustn't be [mis]used in this way, not to add a bunch more unwinder data. Andrew.
