This is the mail archive of the 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?

Andrew Haley wrote:

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

OK, I see. Does the function call count as trap too?

> libc does support thread cancellation points, and it's always
> safe to unwind the stack from one of these.

Well, thread cancellation points are indeed nice, but they occur too rare, at least in the code I'm
now concerned about.  When you say, you understand the mechanics of signal handling right into the
kernel guts, you can perhaps help me with my original concern too, namely how to convert SIGINT and
SIGALRM to properly catchable C++ exceptions.

If you wonder what it might be good for: since years I'm writing on an open source software for
discrete mathematics called polymake.  It consists of an interactive core written in perl and
modules performing massive calculations written, for the sake of efficiency, in C++.  The C++
routines are called directly from the perl code via the special interface, similar to JNI (although
much uglier, but it doesn't matter now).  Thus everything lives in a single process and even in the
single thread (there may exist other threads too, but they are masking these signals away and hence
don't matter).

The signal handling in perl is rather primitive: the handler sets a flag, which is regularly polled
from the main interpreter loop.  For a scripting language it's a sufficient solution.  But not for
the code trimmed for efficiency.

Arrival of the asynchronous signal means that the user has changed his mind and pressed Control-C to
break the current lengthy calculation, or some pre-selected timeout for such calculations has
elapsed.  In both cases the program should return to the interactive shell and wait for the next
user's input, or do something else it might find useful; at any rate, the frames of the interrupted
C++ functions must be properly unwound to avoid memory leaks and other unpleasant surprises.

That's what I need; unfortunately, I have only the utterly faint idea how to implement it.  The
vague plan as for tonight goes as follows: the signal handler analyzes the call stack, finds the
topmost frame belonging to a C++ function and determines the next accessible trap point in it.  Then
it arranges somehow that the execution stops there with a trap, and the trap handler raises a
regular exception.

This plan has two obvious weak points:

1. Until now I had no experience with fiddling stack frames and DWARF data in Linux.  I've got to
read some specs and code; could you give a hint where to begin?

2. It's unclear how to make the program to trap at a prescribed location.  Temporarily modify the
instruction?  Use the debugging registers?  Something else???

If you can give any helpful advices on these topics, you can be sure of an eternal appreciation and
admiration from the discrete geometry community :-)

The "boundary constraints" for the solution are moderate:

1. The signal handling may be slow and clumsy, but shouldn't affect the execution speed in the
uninterrupted case (like the current try & catch implementation in GCC).

2. It should run under modern Linux kernels on Intel/AMD platforms.  MacOS and FreeBSD would be nice
to have, but this can wait.

3. The code to be interrupted is either self-compiled (hence with full control over compiler options
etc.) or is a standard library - no third-party black boxes built by unknown compilers with unknown

Thanks for your attention!

With best regards,
Ewgenij Gawrilow

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