libunwind-devel
[Top][All Lists]
Advanced

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

Re: [Libunwind-devel] [PATCH 1/2] Restore the interpretation of the NULL


From: Konstantin Belousov
Subject: Re: [Libunwind-devel] [PATCH 1/2] Restore the interpretation of the NULL %rbp location as end of frame chain.
Date: Wed, 19 Sep 2012 08:42:58 +0300
User-agent: Mutt/1.5.21 (2010-09-15)

On Tue, Sep 18, 2012 at 08:55:23PM +0200, Lassi Tuura wrote:
> Hey,
> 
> >> src/dwarf/Gparser.c comment "DWARF spec says undefined return address
> >> location means end of stack."
> >>
> > In fact, I was unable to find a justification for exactly the statement
> > from the comment in the documentaion.
> 
> See http://www.dwarfstd.org/doc/DWARF4.pdf section 6.4.4 Call Frame
> Calling Address:
> 
> "If a Return Address register is defined in the virtual unwind table,
> and its rule is undefined (for
> example, by DW_CFA_undefined), then there is no return address and no
> call address, and the
> virtual unwind of stack activations is complete"
Oh, thank you for pointing out.

> 
> And yes, null value vs. undefined location are not the same thing. I
> changed the "null rbp location" check to "null rip location" in the
> PLT fix 
> (http://git.savannah.gnu.org/gitweb/?p=libunwind.git;a=commitdiff;h=f252f5ff4e51af90fd6629f122f72556db94ccb7)
> though certainly won't claim to recall all the details :-)
> 
> > Which is not the same as setting the %rbp location to NULL. FreeBSD
> > startup sequence ATM is to enter usermmode with zero %rbp, which is
> > not compliant, but historically established.
> 
> I confirm Linux does/has done the same; and as you noted, it's
> specified - see also line 83 in src/x86_64/Gstep.c.
> 
> It's not unusual the first non-thread frame in Linuxen also terminates
> in the frame-based unwinder, with the null rbp check. I made the fast
> trace unwinder handle frame-pointer-walked frames because a few very
> prominent frames lack dwarf info - the first (non-thread) entry point
> frame, PLT, etc.
> 
> > Looking at the unpatched Gstep.c, I see the following sequence
> > of the events:
> >
> > 1. %rbp is zero, as read by DWARF_GET_LOC().
> > 2. The rip_loc is set to DWARF_NULL_LOC, and then reassigned to cursor
> >    dwarf.loc[RIP].
> > 3. The check !DWARF_IS_NULL_LOC (c->dwarf.loc[RIP] returns false, which
> >    causes assignment the c->dwarf.ip = 0.
> > 4. The last non-return statement in unw_step() is executed, which verifies
> >    that stepper has made a progress. It would not on the next step,
> >    returning UNW_EBADFRAME.
> >
> > My patch explicitely handles the case of zero %ebp if dwarf unwinder
> > already declained,
> 
> Thanks for this! Are we talking about this code in src/x86_64/Gstep.c?
> 
>  217       if (c->dwarf.ip == prev_ip && c->dwarf.cfa == prev_cfa)
>  218         return -UNW_EBADFRAME;
> 
> In that case, any idea why the previous unw_step() didn't flag it as
> the last frame and return zero? It seems it's stuck looping on the
> same frame if that condition trips? The previous frame should have
> triggered either code around line 83 (dwarf-based; or the end-of-stack
> code from Gparser.c) or line 152 (frame-pointer based), and unw_step()
> should have returned zero? Or did I misunderstand?

Goal of my patch is to make the code at line 152 to result in actually
returning zero from unw_step(). I do not see how frame-based unwinder
could return zero in unpatched code.

Attachment: pgp_0vbjIvmIt.pgp
Description: PGP signature


reply via email to

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