[Mono-dev] Need help with signal handlers.
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
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
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.
More information about the Mono-devel-list