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: Thu, 20 Sep 2012 15:28:44 +0300
User-agent: Mutt/1.5.21 (2010-09-15)

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

Attachment: pgpkWazhapi2r.pgp
Description: PGP signature


reply via email to

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