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?


Ewgenij Gawrilow wrote:
>>>> 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.

That is not practically everywhere: the compiler knows that some operations trap,
and generates abnormal edges in the control flow graph for them.  Without these
edges it's impossible to generate correct code.

If every instruction may trap and an exception may be thrown from them, then there is
an abnormal edge from every instruction to an exception handler.

> 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.  

And me.

> Is this implementation believed to be robust
> against future kernel development?

Yes, it is.  The kernel interfaces are historically very stable.

> 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?

I don't think so.  libc does support thread cancellation points, and it's always
safe to unwind the stack from one of these.

Andrew.



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