Re: mach in signal handler
Re: mach in signal handler
- Subject: Re: mach in signal handler
- From: Terry Lambert <email@hidden>
- Date: Thu, 1 Feb 2007 22:04:48 -0800
On Feb 1, 2007, at 8:29 PM, Steve Checkoway wrote:
Earlier, I asked on darwin-dev if the mach APIs, in particular,
vm_region(), could be called from a signal handler. Here's the
thread, <http://lists.apple.com/archives/darwin-dev/2007/Jan/msg00048.html
>
Dave Zarzycki said that if the mach based APIs are interruptible by
signals, then then answer is no, but that he was unsure if that were
the case. I am throughly unfamiliar with the darwin source, so I'm
not sure where to even begin looking for that. I was hoping someone
could point me in the right direction.
Signals are implemented as Mach ASTs using the BSD AST, which is
basically a bit in the ast flags that gets checked when ast_taken() is
called. This is basically called during trap and exception handling.
So it's possible that a signal could abort a Mach call, if the call
happened on an interruptible thread at the right time.
In general, the reason to fear calling things in signal handlers is
that there are certain things that, if you call them in a signal
handler, there's potentially associated user space state that does not
get reset as a result of the signal.
The problem isn't that you are making the call, per se, it's that the
call may already be in progress and partially complete at the time the
signal handler fires and reenters the called code.
A good example would be "malloc": it's always wrong to allocate or
free memory in a signal handler.
In general, anything that's implemented using statefulluser space
stubs (or almost completely in user space) is not safe to call from a
signal handler because of the accumulated state from a call already in
progress. If the code being called is not reentrant, you shouldn't
call it from a signal handler (or even from a thread, unless you
protect the calls by a mutex).
Also in general, mixing BSD and Mach semantics is not a good idea,
since BSD is layered on top of Mach.
For the specific call you are talking about, it looks like it's safe
(i.e. the worst case outcome is that you try to call it, it gets
interrupted, and you don't get the answer you wanted to get).
Just as a general rule, signal handlers on UNIX systems should
probably only ever be used to set global volatile variables that you
then check somewhere else, not in the signal handler, to see if the
handler fired.
Signals are persistent conditions, not events, which means that if
something happens that would cause a signal handler to fire multiple
times in rapid succession, then you will only see the handler fire
exactly once.
As such, signals are generally only useful for async notification of
an even that you can check yourself with some other function --e.g.
you get a SIGCHLD, the handler fires, you set a global volatile flag,
the select() or other call you were hung in returns -! with errno set
to EINTR, you poll the status on all your childrent using one of the
wait(0 functions with the WNOHANG argument, you dispatch a work
function for each one that polls to be in the condition you care about
handling for a SIGCHLD, and then you restart the function that
returned the EINTR.
Personally, Unless your intent is to implement something like a
SIGINFO handler (where you have a monkey at the keyboard of a terminal
window typing ^T to cause the handler to fire), I would not call this
function from a signal handler; even then, I'd be more likely to set a
volatile global and check it at every point I have a blocking function
that I allowed to be interrupted by the signal (via a call to
sigprocmask(2) before the blocking function, re-blocking the signal
after the fact), and check the volatile and do the work there, arther
than on the signal handler. You basically don't know what state your
stack is in at the time it fired, and the sigaltstack function doesn't
work the standard way in Tiger or earlier.
-- Terry
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-kernel mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden