This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: How to benefit from asynchronous unwind tables?


>>> libgcj (GCC's java runtime library) does exactly what you describe for
>>> synchronous signals (SIGSEGV, SIGFPE).  Throwing exceptions through such
>>> signal frames does work for both i386 and x86_64 (as well as many other
>>> architectures) on linux.  Unwinding from arbitrary asynchronous signals
>>> (SIGUSR1 etc.) is not supported.
>>>
>>> The code that does it can be found in libjava/prims.cc
>>>
>>
>> Do you (or somebody else) know by chance what's the major difference
>> between the signal handler
>> frames generated by SIGFPE and, say, SIGINT?  Is it documented anywhere?
>>
> 
> The problem isn't the signal handler frames.  The unwinder can unwind
> through them all.
> 
> The problem is that you must have accurate unwind tables in 100% of your
> code (including libc, ld.so, and all other possible libraries that you
> might be calling) if you want to be able to unwind from asynchronous
> signals.
> 
> With SIGFPE and SIGSEGV, the compiler knows exactly where they might be
> generated and only needs accurate unwind tables at those locations.
> 

Well, these signals can be triggered at every instruction referring to memory or working with
floats, that is, practically everywhere.  They can also occur within some system library.  What
would happen, for example, if one calls strlen() with an invalid string address?  Will the unwinder
find its way out of libc?  But it's probably a contrived example, it's OK if the program just
terminates in such case.

I have, however, two further questions.  At first, the code you have pointed me to seems to use some
suspicious (or at least high-secret) kernel features.  The use of the sigaction field sa_restorer is
"obsolete" in Linux according to the man page, its semantics is not described at all, and the
libjava code stores there a hand-written assembler routine, the exact meaning of which could be
probably understood by hard-core kernel hackers only.  Is this implementation believed to be robust
against future kernel development?

The second question is about the possibility to analyse and manipulate the stack frames.  If the
asynchronous signal handler would find out that the topmost frame belongs to a system library (e.g.
by reading /proc/self/maps), it could descend to the first frame belonging to the own executable and
manipulate the return address such that after returning from the signal handler the library call
would regularly finish and then the execution would jump to a C++ routine throwing a desired
exception.  I'm wondering whether in libgcc or somewhere else there are some functions working with
stack frames this way?

Thanks for your patience!
Ewgenij


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]