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.
pgpoBohr1f7Rp.pgp
Description: PGP signature
_______________________________________________ Libunwind-devel mailing list [email protected] https://lists.nongnu.org/mailman/listinfo/libunwind-devel
