• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: mach in signal handler
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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


  • Follow-Ups:
    • Re: mach in signal handler
      • From: Cyrus Harmon <email@hidden>
    • Re: mach in signal handler
      • From: Steve Checkoway <email@hidden>
References: 
 >mach in signal handler (From: Steve Checkoway <email@hidden>)

  • Prev by Date: mach in signal handler
  • Next by Date: Regarding Hostname of Router!!
  • Previous by thread: mach in signal handler
  • Next by thread: Re: mach in signal handler
  • Index(es):
    • Date
    • Thread