[Mono-dev] Need help with signal handlers.

Jonathan Pryor jonpryor at vt.edu
Fri Aug 19 22:22:38 EDT 2005

On Fri, 2005-08-19 at 15:43 -0700, Mike Hull wrote:
> I'm trying to pass signals received with signal.h into managed code.  
> After I mono_runtime_exec_managed_code I can not receive signals using 
> signal(sig,signal_handler).  If I don't mono_runtime_exec_managed_code I 
> receive the signals just fine.

You're in a world of hurt. :-)

Mono.Posix.Syscall.signal() is horribly, horribly broken.  How broken?
It takes a raw `int' as the signal number to catch.  You *cannot* use
Mono.Posix.Signals because those don't match *ANY* operating system's
values.  Consequently, it's inherently non-portable.

Mono.Unix.Stdlib.signal() is the replacement, but it isn't without the
next problem.

The larger problem is one of reentrancy: Mono is not reentrant, and
neither is the P/Invoke layer.

Reentrancy is similar to thread safety, but different: when a signal
occurs, a (potentially random) process thread is "hijacked", a new stack
frame is added (or worse, the current stack frame is re-used), and the
signal handler is executed.  (Since an existing thread is re-used, and
probably the most recently executing thread, normal thread-safety tricks
such as mutexes won't work -- you have to protect against the *same*
thread re-entering the currently executing function.  Fun.)

The only safe thing you can do is call other reentrant functions, and
*most* functions are NOT reentrant (malloc(3) isn't, neither is free(2),
function calls are "iffy" depending on how much stack space you

In short, signal handlers are a whole new world of pain.  Managed code
only makes things worse, since the entire P/Invoke layer isn't
reentrant, so you risk many unknowns just trying to use a managed
delegate as a signal handler, never mind doing anything complicated from
the handler.

Thus, the advice: assuming you risk using a signal handler in managed
code, all you can do from managed code is modify a variable.  That's it.
Anything else, *especially* a P/Invoke call, is suspect.

Alternatively, all your signal handlers should be implemented in C.  You
could hook them up from C#.  If you do this, take care that your handler
only calls reentrant functions.

 - Jon

More information about the Mono-devel-list mailing list