On Thu, Sep 20, 2012 at 07:49:00AM +0200, Lassi Tuura wrote: > Hey, > > >> > 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. > > You wouldn't happen to have a debug log for that? I am unfortunately > not able to try the code just now, but from what I recall and reading > the code now, it should come into the "DWARF failed" branch with ret < > 0, and should either set ret to zero via calls (mainly dwarf_get()), > or set it to 1 or 0 in the if block at the end. > > For the particular case of zero rbp for the last frame, it should > return with the ret = 0 from the dwarf_get(), with a few intermediate > things done in between.
Sorry, I do not understand what you wrote. I see exactly two places where a return from unw_step() with ret == 0 happens. First is the case of dwarf_step() returning non-negative value or null location for %rbp, at the block starting at line 83, as discussed above. Second case is the frame based unwinder, when unw_is_signal_frame() detected either signal or syscall frame (without dwarf annotations) but unw_handle_signal_frame failed. Any other path through the unw_step() results in non-zero return. Below is the fragment of the patched libunwind debug output from the Gtest-concurrent which was modified to only create one thread. I put the whole log of the _unpatched_ libunwind run at the http://people.freebsd.org/~kib/misc/Gtest-concurrent.log And, a detail there is that both tests were done on the modified FreeBSD, with libc patched to contain the dwarf unwind info for most asm code. I did not committed the patch into FreeBSD HEAD yet. >_Ux86_64_step: returning 1 >_Ux86_64_step: (cursor=0x7fffffbd8b30, ip=0x0000000800e870a4, >cfa=0x00007fffffbd97d0) >put_rs_cache: unmasking signals/interrupts and releasing lock >access_mem: mem[00007fffffbd97f8] -> 0 >_Ux86_64_dwarf_step: returning 1 >_Ux86_64_step: returning 1 >_Ux86_64_step: (cursor=0x7fffffbd8b30, ip=0x0000000000000000, >cfa=0x00007fffffbd9800) >_Ux86_64_dwarf_find_proc_info: looking for IP=0xffffffffffffffff >_Ux86_64_dwarf_callback: checking /usr/home/kostik/build/bsd/libunwind/build-x86_64/tests/.libs/Gtest-concurrent, base=0x0) >_Ux86_64_dwarf_callback: checking libunwind-x86_64.so.8, base=0x80081b000) >_Ux86_64_dwarf_callback: checking libunwind.so.8, base=0x800a3d000) >_Ux86_64_dwarf_callback: checking liblzma.so.5, base=0x800c5c000) >_Ux86_64_dwarf_callback: checking libthr.so.3, base=0x800e7f000) >_Ux86_64_dwarf_callback: checking libc.so.7, base=0x8010a2000) >_Ux86_64_dwarf_find_proc_info: IP=0xffffffffffffffff not found >put_rs_cache: unmasking signals/interrupts and releasing lock >_Ux86_64_dwarf_step: returning -10 >_Ux86_64_step: dwarf_step() failed (ret=-10), trying frame-chain >access_mem: mem[00007fffffbd97f0] -> 0 >_Ux86_64_step: NULL rbp loc, returning 0
pgprtAMl1zlnY.pgp
Description: PGP signature
_______________________________________________ Libunwind-devel mailing list [email protected] https://lists.nongnu.org/mailman/listinfo/libunwind-devel
