[Ecls-list] Making an external signal handler play nice with embedded ECL

Juan Jose Garcia-Ripoll juanjose.garciaripoll at googlemail.com
Sat Feb 26 19:48:26 UTC 2011


On Sat, Feb 26, 2011 at 3:34 AM, Nils Bruin <nbruin at cecm.sfu.ca> wrote:

> I did not quite understand the mprotect trick first but I think I do now.
> Let me verify:
>  - If the ECL signal handler finds that the interrupted code is not "safe",
> then the handler stores the signal information and marks "env" read-only.
>  - The next time "env" is accessed, a SIGSEGV will be triggered, which the
> ECL signal handler recognises as being triggered by the mprotected region.
>
 - If safe, the handler now processes the queued signals and we're done.
>

That's it! This is a trick that I learned in some blog post, but I slightly
adapted it.


> Q: Is it guaranteed that this will happen in a "safe" area or is it
> possible that the signal handler discovers that it is still not safe and
> hence leaves the queue as is?
>

More or less this is what I expect. I try to keep the signal-protected
regions as small as possible, but sometimes it is difficult. The pattern I
tried to implement is the following one (in the C core)

* Assign 1 to the flag that blocks signals
* Execute a small section of protected code.
  Here the signal handler may receive SIGINT and mark the environment as
read-only
* Assign 0 to that flag
  This may trigger a SIGSEGV if the environment was marked read-only

The protected code should not _write_ to the environment during the
protected region. This is normally the case.


> It still leaves a small window where ECLs handlers are in place but ECLs
> environment isn't yet. If it would be possible to set the ECL signal
> handlers to "queue, don't handle" before entering ECL and enable them once
> the ECL environment is in place it might be possible to remove this one
> glitch.


In the window from the signal handler swap until ECL is booted, ECL will
simply discard all signals, because the signal queue is not installed and
ECL is not marked as booted. Or do you perform the swap every time that ECL
code is executed?

Also, this solution would probably not work very well for lots of very small
> calls into ECL, due to the overhead of all the sigaction calls. I don't
> think this is much of an issue at the moment, but if it were I imagine the
> proper solution would be to make sage's signal handler ECL-aware and take
> appropriate action there (and hooks in the ECL API would help for that)
>

Your previous suggestion, using some API, looks fine, but it would not work
with the mprotect() trick, unless your code uses sigaction() and passes the
appropriate records


> In fact, ECL does seem to have a small race condition itself (as most
> programs seem to have): If I run ECL (stand-alone) and truly bombard it with
> SIGINTs, I get a segfault.


I will look into that.

Juanjo

-- 
Instituto de Física Fundamental, CSIC
c/ Serrano, 113b, Madrid 28006 (Spain)
http://juanjose.garciaripoll.googlepages.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mailman.common-lisp.net/pipermail/ecl-devel/attachments/20110226/60537030/attachment.html>


More information about the ecl-devel mailing list