determine whether code is running in a signal handler context

Carlos O'Donell carlos@redhat.com
Thu Oct 19 03:12:00 GMT 2017


On 10/18/2017 07:39 PM, Will Hawkins wrote:
>> This is not true. It is architecture dependent. For examples on how complex
>> it is to get this 100% right you have to go read gdb sources to see how
>> they do this. It is non-trivial. It might be easier to use a library like
>> libunwind to determine this for you (if it even can).
> 
> This is a fascinating thread. The downside to using libunwind is that,
> iirc, it requires debugging information in the binary to work. In other
> words, it would not work on a stripped binary. Please correct me if I am
> wrong.

No. libunwind only needs .eh_frame/.debug_frame, not debug information.

Some unwinders can operate without debug information, but only if the
architecture, and ABI layout of the frame allow unwinding with a frame
pointer. On 32-bit ARM, at least for a while, the frame pointer was
synthesized by the compiler to avoid using a fixed frame pointer and
free up such a pointer for the compiler to use. The side effect is that
you always need the DWARF unwind information to unwind a frame, but you
do *not* need debug information. One should be careful not to confuse
the two. The generic term "debug information" can mean a lot more,
including all the DWARF required to debug the program. You don't need
this to unwind, you only need .eh_frame/.debug_frame. As you see 32-bit
ARM was leading the charge here to free up a register for compiler use,
and now it's common practice on x86_64 and x86 to compile without the
frame pointer, and so you must have auxiliary information to unwind,
and you can't write a by-hand unwinder that follows the frame pointer.

The complex part is that to unwind from an asynchronously delivered signal
you need asynchronous unwind tables which describe how to unwind from
any point in the program, because when the signal arrives you may attempt
an unwind from any point to an outer frame. Usually the unwind information
can be elided to the point at which function calls are made, or try/catch
blocks.

But you need not unwind from the signal handler, you need only detect
that you are *in* a signal handler, and libunwind might have enough
heuristics for the machines you care about that it might work. I have
not tried it though, so YMMV.

-- 
Cheers,
Carlos.



More information about the Libc-help mailing list