Re: mach in signal handler
Re: mach in signal handler
- Subject: Re: mach in signal handler
- From: Steve Checkoway <email@hidden>
- Date: Thu, 01 Feb 2007 22:45:25 -0800
Terry Lambert wrote:
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.
We're very careful not to call malloc or anything that may call malloc
(such as printf) in the signal handler. If we don't actually plan to
leave the signal handler but instead kill the process, is this still a
problem?
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.
If I remember my graduate OS class correctly, there's some sort of UNIX
server process that sits outside the kernel.
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).
Would I not get the answer I wanted in the call to the signal handler,
or in a previously executing but interrupted call?
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.
In general, I agree. What we do in this specific case, is build a crash
log including a backtrace (being very careful not to call forbidden
functions), fork a new process, send the data to it and have it do
things like symbol lookups and throw up a dialog informing the user of
the crash, etc.
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.
Once is all we need. We will never return from the handler. I don't
recall if we perform suicide or patricide, but one way or another the
process will never return from the handler. If the handler is invoked
again, we throw up our hands and just die.
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.
How does it work in Tiger? I know we use it.
--
Steve Checkoway
_______________________________________________
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