Technically, I don't think the cfa is absolutely guaranteed to be the SP just before the call. That's just the most common and straightforward way to set it up; the dwarf cfi can set it to whatever it wants as long as it can get to the saved state from it. It's rather unlikely to be anything but a constant offset from that SP.
As I recall, the spec has confusing language like "the cfa is commonly defined as the SP just before the call", which isn't a definition at all. Sent via DroidX2 on Verizon Wireless™ -----Original message----- From: Arun Sharma <[email protected]> To: Lassi Tuura <[email protected]> Cc: Steve Fink <[email protected]>, [email protected] Sent: 2011 Oct, Sat, 29 01:02:56 GMT+00:00 Subject: Re: [Libunwind-devel] local vars On Fri, Oct 28, 2011 at 9:25 AM, Lassi Tuura <[email protected]> wrote: > Hi, > >> I can't think of anything obvious that'd break if we returned a >> different answer for UNW_X86_64_CFA. Let me think about this a bit >> more before attempting to implement something. > > Hm, are you certain about this? > After this patch: --- a/tests/Gtest-bt.c +++ b/tests/Gtest-bt.c @@ -59,7 +59,7 @@ ucontext_t uc; static void do_backtrace (void) { - unw_word_t ip, sp, off; + unw_word_t ip, sp, off, cfa; unw_proc_info_t pi; int ret; @@ -74,6 +74,8 @@ do_backtrace (void) { unw_get_reg (&cursor, UNW_REG_IP, &ip); unw_get_reg (&cursor, UNW_REG_SP, &sp); + unw_get_reg (&cursor, UNW_X86_64_CFA, &cfa); + printf("ip=%lx sp=%lx cfa=%lx\n", ip, sp, cfa); buf[0] = '\0'; if (unw_get_proc_name (&cursor, name, sizeof (name), &off) == 0) { I get: ip=400c59 sp=7fffffffd900 cfa=7fffffffd900 ip=40195b sp=7fffffffda40 cfa=7fffffffda40 <-- bar()'s frame ip=40199b sp=7fffffffde30 cfa=7fffffffde30 ip=332d01d8b4 sp=7fffffffdf00 cfa=7fffffffdf00 ip=400b69 sp=7fffffffdfc0 cfa=7fffffffdfc0 note how (cfa == sp) is always true. Whereas DWARF defines cfa to be the sp *before* the call. gdb shows: Breakpoint 1, bar (v=1) at Gtest-bt.c:139 139 { (gdb) info frame Stack level 0, frame at 0x7fffffffde30: rip = 0x400f50 in bar (Gtest-bt.c:139); saved rip 0x40199b called by frame at 0x7fffffffdf00 source language c. Arglist at 0x7fffffffde20, args: v=1 Locals at 0x7fffffffde20, Previous frame's sp is 0x7fffffffde30 Saved registers: rip at 0x7fffffffde28 I'm essentially thinking of changing the return value of unw_get_reg (&cursor, UNW_X86_64_CFA, &cfa), without touching any other implementation details. Does that affect the fast trace implementation? -Arun
_______________________________________________ Libunwind-devel mailing list [email protected] https://lists.nongnu.org/mailman/listinfo/libunwind-devel
