[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [libunwind] problems parsing dwarf frame info on amd64 optimized cod

From: Max Asbock
Subject: Re: [libunwind] problems parsing dwarf frame info on amd64 optimized code
Date: Fri, 12 Mar 2004 10:37:02 -0800
User-agent: KMail/1.5.4

On Friday 12 March 2004 10:12, David Mosberger wrote:
> >>>>> On Mon, 8 Mar 2004 10:49:45 -0800, Max Asbock <address@hidden> said:
>   Max> Hi all,
>   Max> I am trying to parse the dwarf frame info on amd64 using
>   Max> libunwind which I had to slightly modify to run on amd64.
>   Max> The parser works correctly in unoptimized code that uses frame 
> pointers.
>   Max> When I turn on the -O flag things fall apart. This is with gcc 3.2.2.
>   Max> The parser finds two rules in the CIE:
>   Max> CFA_def_cfa r7+0x8           (rsp)
>   Max> CFA_offset r16 at cfa-0x8  (return address)
>   Max> and then in the FDE it finds:
>   Max> ...
>   Max> CFA_def_cfa_offset <offset>
>   Max> ...
>   Max> This works for stepping from the first frame to the second, but
>   Max> on the next step it fails, since the CFA is read again from r7 (rsp)
>   Max> which hasn't changed. And it seems that the CFA <offset> is the
>   Max> offset relative to the current CFA, not relative to the value in rsp.
> Hmmh, I suspect the bug is in apply_reg_state().  It probably should
> use c->cfa instead of unw_get_reg() "under the right circumstances".
> I'll see if I can reproduce the problem with x86.  What test-case did
> you use?

I sent mail about this to the gcc mailing list and got confirmation that
something like the following will work:

Frame 1:
cfa = r7 + <offset>     /* (r7 is rsp) */
if (r7 unspecified)   r7 = cfa
Frame 2:
cfa = r7 + <offset>

In apply_reg_state() this could translate to:

 for (i = 0; i < DWARF_NUM_PRESERVED_REGS; ++i)
      switch ((dwarf_where_t) rs->reg[i].where)
        case DWARF_WHERE_SAME:
            if (i == <REGNUM_SP>)
             if (ret = dwarf_put(c, c->loc[i], cfa))
               return ret;

The test case I am using is bt.c with the signal stuff removed. 
After applying this change it works.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]