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

Reply via email to