ARM Linux EABI: unwinding through a segfault handler

Andrew Haley
Thu Oct 27 09:06:00 GMT 2011

On 10/27/2011 02:15 AM, Paul Brook wrote:
>>>> So, suggestions welcome.  Is there a nice way to detect a signal frame?
> That just makes me ask why are you're trying to detect a signal frame in the 
> first place?

Because I need backtrace() to work when called from a signal handler.

>>> Libunwind also reads the IP to detect signal frames on ARM Linux:
>>> signal_frame.c;hb=HEAD
>>> I'd also be interested if there are better approaches to detect them. :)
>> There aren't better ways - this is pretty much the standard for
>> on-stack signal frames :-)
>> I thought we used a handler in GLIBC that was properly annotated,
>> nowadays, but I might be mistaken.
> We do, but the annotation is fairly approximate.
> Short story is that the standard EABI unwinding opcodes can't describe a 
> signal frame accurately.  Especially if we don't know (when building glibc) 
> whether the application will be using VFP.
> The good news is that The EABI unwinding tables delegate all interesting 
> behavior to the personality routine (c.f. DWARF unwinding where the frame 
> description is parsed by libunwind).  In order to accurately unwind signal 
> frames you need to have the sa_restorer functions reference a custom 
> personality routine that does the unwinding.
> If something is specifying a non-default sa_restorer, then you loose.
> Don't Do That :-)
> While Richard is correct that the ARM EABI only requires unwinding information 
> at call sites, in practice as long as you use and accept the limitations 
> imposed by -fnon-call-exceptions, and ignore stack overflows, it should be 
> sufficient. 

Sure, but without the fix I provided it doesn't work.  The problem is
that the return address points to the faulting instruction, not the
following instruction.  In the generic unwinder code, the boolean
ip_before_insn is set to cope with this.  The ARM unwinder does not
set this, so the backtrace does not work.

All you have to do to make it work is set ip_before_insn when a signal
frame is detected.  The patch I provided, which unfinished is quite
robust, and works in the same way as the libunwind code that parses
the EABI information.


More information about the Gcc mailing list