[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [libunwind] problems parsing dwarf frame info on amd64 optimized cod
Re: [libunwind] problems parsing dwarf frame info on amd64 optimized code
Fri, 12 Mar 2004 10:37:02 -0800
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
> 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:
cfa = r7 + <offset> /* (r7 is rsp) */
if (r7 unspecified) r7 = cfa
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)
if (i == <REGNUM_SP>)
if (ret = dwarf_put(c, c->loc[i], cfa))
The test case I am using is bt.c with the signal stuff removed.
After applying this change it works.