[Top][All Lists]

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

Re: [Libunwind-devel] question about is_signal_frame and usage

From: Jan Kratochvil
Subject: Re: [Libunwind-devel] question about is_signal_frame and usage
Date: Tue, 27 Feb 2007 22:19:33 +0100
User-agent: Mutt/1.5.13 (2007-02-12)


this issue is out of the David Mosberger-Tang's code as this functionality
(`decrease_ip' code) is implemented only in the Frysk's fork of libunwind
        cvs -d :pserver:address@hidden:/cvs/frysk co libunwind

On Tue, 27 Feb 2007 20:15:19 +0100, Corey Ashford wrote:
> I've been debugging a test case (a variant of test-async-sig) that 
                        run-ptrace-signull / test-ptrace-signull.c ?

> occasionally gets an error during unwinding through a signal handler. 
> The error occurs when the signal interrupts the first instruction of 
> function.
> I've narrowed down the problem to this sequence in dwarf/Gparser.c:
> > static int
> > fetch_proc_info (struct dwarf_cursor *c, unw_word_t ip, int 
> > need_unwind_info)
> > {
> >   int ret, dynamic = 1;
> > 
> >   /* In the current (lowest) frame we must not touch `ip' as the current
> >      address is where we stand.  On the other hand any upper frames will 
> >      stand
> >      on the next instruction behind our call which may have a different 
> >      stack
> >      DWARF information (for `stdcall' called functions) or the next 
> >      instruction
> >      even may belong already to a different continuing function.
> >      Also signal frames got invoked from the instruction we want to 
> >      analyze.  */
> >   if (c->decrease_ip)
> >     --ip;
> > 
> ...
> The problem here is that the frame we are unwinding is no longer a 
> "signal frame" (I think).  In my current PowerPC port, a signal frame is 
> recognized by looking for the signal return trampoline code at the 
> current IP address.

There are two code ways for handling signal handlers.  One is by the DWARF CIE
augmentation "S" and the other is by raw disassembly / binary compare.
The former is by is_signal_frame() (dwarf/Gparser.c), the latter is by
unw_is_signal_frame() (ARCH/Gis_signal_frame.c).

> Because this function IP is not recognized as a signal frame, 
> c->decrease_ip is set to true, which moves the IP out of the function to 
> whatever cruft precedes the function.  Consequently, the proc info is 
> not found and returns an error.

There is that `decrease_ip' memory to remember that last frame's
is-signal-frame boolean in the cursor.  The IP decrease must be applied one
step later.  It is correct that in "this function" (where we stand at its first
instruction) the signal frame is not recognized.  But it should have been
recognized and stored one step earlier.

> Have I misunderstood how is_signal_frame is supposed to be implemented? 
>  Currently, I use is_signal_frame in ppc64/Gstep.c to determine if I 
> should use the ucontext record on the stack to restore the registers. 

I believe you exchange here the DWARF and non-DWARF way.  In the DWARF way of
is_signal_frame() implementation by "S" augmentation we do not need to do
special ucontext handling as the DWARF general unwinder takes care of it.

In the non-DWARF way you need to handle ucontext by hand but you should
implement PPC unw_is_signal_frame() based on the disassembly / binary compare.

I would also rather implement the DWARF for signal frames in glibc.
I pushed it only for i386+x86_64 before:

Kernel PPC VDSO looks to me a bit broken, it has DWARF but the augmentation for
__kernel_sigtramp_rt64() does not contain the "S" mark, weird.

On i386/x86_64 there is Linux kernel "/proc/sys/kernel/vdso" where the code
should work both with it being 1 (default - kernel VDSO) and 0 (glibc).
I did not find "/proc/sys/kernel/vdso" on PPC at all, though, it looks there as
always turned on.

Don't hesitate to ask and save more time, the text above was pretty brief.


reply via email to

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