[Ecls-list] CVS HEAD threads and signal handling

Matthew Mondor mm_lists at pulsar-zone.net
Sun Oct 18 23:10:07 UTC 2009


On Sun, 18 Oct 2009 17:58:03 +0200
Juan Jose Garcia-Ripoll <juanjose.garciaripoll at googlemail.com> wrote:

> Could you elaborate this a little bit, please? Is this via Ctrl-C, or
> via "kill -SIGINT whatever..." Under which conditions is the loop
> entered? Multithreaded code? Already something running in the
> background?

The report was imprecise, sorry about that.  Indeed, this happens if I
kill -INT the ECL process, as well as if I issue CTRL-C at the terminal
at its REPL, which causes the OS to also signal the ECL process with
SIGINT.  In both cases a SIGSEGV then occurs and an endless loop:

 25638      1 ecl      CALL  read(0,0xbb704000,0x1000)
 25638      1 ecl      RET   read -1 errno 4 Interrupted system call
 25638      1 ecl      PSIG  SIGINT caught handler=0xbbb93680 mask=(): code=SI_NOINFO
 25638      1 ecl      CALL  mprotect(0xbb8d4000,0x28c,1)
 25638      1 ecl      RET   mprotect 0
 25638      1 ecl      CALL  setcontext(0xbfbfdda4)
 25638      1 ecl      RET   write JUSTRETURN
 25638      1 ecl      PSIG  SIGSEGV caught handler=0xbbb937d0 mask=(11): code=SEGV_ACCERR, addr=0xbb8d4000, trap=6)
 25638      1 ecl      CALL  issetugid
 25638      1 ecl      RET   issetugid 0
 25638      1 ecl      CALL  issetugid
 25638      1 ecl      RET   issetugid 0
 25638      1 ecl      PSIG  SIGTERM SIG_DFL: code=SI_USER sent by pid=763, uid=1000)

And this indeed is an ECL built with thread support.  I didn't test
this with non-threaded ECL yet.

Note that SIGTERM causes ECL to exit as usual, even when it's stuck in
that loop.  It's possible that the occurance of SIGSEGV happens because
of a bug in the SIGINT handler code, I've not looked at the source of
the handlers lately.  Also, you said that a new thread should be
created at that point but the segfault seems to occur before this
happens.

> I have been pondering some mechanism to implement signal handlers in
> Lisp. Right now SIGSEGV, SIGFPE and SIGBUS are reinterpreted as
> conditions, SIGINT is the only one which does create new handling
> threads. Maybe we could use a global variable to denote one of the
> following behaviors:
> 
> - A thread designator, denoting the thread that wants to receive the
> signal reinterpreted as condition.
> - A function that does the job.
> - NIL to simply ignore.
> - T to use the default behavior and enter the debugger.

Allowing to provide Lisp code to handle arbitrary signal handlers would
indeed be nice.

> I see this is needed when the user is blocking input in a way such
> that the debugger can not create a toplevel. Maybe this is what is
> happening in your case, but it something we have to consider for the
> future.

That's possible.  In this case, as expected read(2) is interrupted by
the SIGINT signal and returns error (-1) with errno set to EINTR.  A
single threaded C application would have the choice to supply a SIGINT
handler and restart the read(2) syscall, or to tell the signal system
to automatically restart syscalls (i.e. SA_RESTART bit in sigaction(2)
man page).

Or yet again the application can decide to stop reading alltogether at
that point and do something else (i.e. check a volatile flag which the
SIGINT handler set to true/1 and perform the wanted action in the main
loop, minimizing the work signal handler functions have to do (for
instance, not all actions are signal-handler safe, and sometimes it's
best to defer them to the main loop of the program)...

Thanks,
-- 
Matt




More information about the ecl-devel mailing list