• 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: SIGPIPE and SIG_IGN
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: SIGPIPE and SIG_IGN


  • Subject: Re: SIGPIPE and SIG_IGN
  • From: Terry Lambert <email@hidden>
  • Date: Tue, 19 Jun 2007 03:35:51 -0700

On Jun 18, 2007, at 6:10 PM, Glenn Anderson wrote:
At 5:30 pm -0700 18/6/2007, Terry Lambert wrote:
This also means that the signal will not get sent if you are ignoring it, and it's in your process signal mask (sigaction() is generally preferred to calling signal(), but either should work).

Near the end of signal.h there is this: /* * signals delivered on a per-thread basis. */ #define threadmask (sigmask(SIGILL)|sigmask(SIGTRAP)|\ sigmask(SIGIOT)|sigmask(SIGEMT)|\ sigmask(SIGFPE)|sigmask(SIGBUS)|\ sigmask(SIGSEGV)|sigmask(SIGSYS)|\ sigmask(SIGPIPE))

Is this not true?

It is has been my experience that if you want to ignore SIGPIPE, you have to ignore it on every thread that could trigger it (ie: call signal(SIGPIPE, SIG_IGN) on every thread that writes to sockets that could close), you can't just ignore it for the whole process.


I pretty much rewrote all of the signal handling code in the kernel for UNIX conformance for Leopard, so I'm rather familiar with the code here for both Tiger and Leopard. 8-).

-

The threadmask is only consulted when threadsignal() is called, which only happens in catch_exception_raise(), and in proc_exit() or vproc_exit() when the process is exiting and may need to signal a specific thread in a sigwait().

Neither of these happen for a SIGPIPE.

The catch_exception_raise() only happens when you raise an exception on an exception port as a result of sending a Mach message, usually from user space, usually as a result of a C++ exception being thrown.

-

There are two levels of masking, one for threads, and one for the process. If you set the process mask, the signal is not delivers to the process, period. You can also block the delivery via sigblock() (but it gets pended, so when it's unblocked, it will get delivered).

If the signal is masked on a thread but not on a process, then it will get delivered to any thread in the process except the thread(s) that masked it. This happens in the BSD AST handling code when any given thread that does not have the signal masked runs up to the user/kernel boundary, which triggers the trampoline code to run in user space to fire the signal handler on that thread (it does this by returning to an address offset from the intended system call return address). The user space signal handler fires, and, on completion calls __sigreturn() to throw it back into the kernel to complete the call that you were trampolined from, and return to user space.

-

The main issue that people tend to miss when they mix threads and signals is that all of the standard POSIX (and BSD) interfaces are process-wide _and MUST be_, since they predate the concept of pthreads.

The only way to deal with threads issues directly is to use the threads APIs AFTER using the standard historical APIs; specifically, you want to mask the signals using the API:

	sigprocmask()

And you want to deal with the thread masking to mask it for all threads via pthread_sigmask() on a thread-by-thread basis; there's sample code that gives a (really: don't use it directly) abbreviated example here:

<http://www.opengroup.org/onlinepubs/009695399/functions/pthread_sigmask.html >

But I *HIGHLY* recommend the tutorial in the O'Reilly pthreads book.

--

From the description, without a cut down test case and a bug filing including the test case, we can't really help you further, other than to point you at documentation. What you have described seeing should not be happening, (and doesn't according standards-based testing). What is most likely happening is that you have a library or a class, template, etc., which is either creating a thread behind your back, or is messing around with the signal mask for the thread and/or process.

Note that the standard template library *will* create threads on your behalf when you utilize some templates, so that could be your culprit.

In general, the most appropriate approach is to designate a signal thread by storing it's pointer off, and if you get the signal on a thread other than the signal thread (pthread_self() doesn't match the catcher thread's ID), then re-throw it to the correct thread using pthread_kill().

In the case that you are attempting to ignore a signal entirely, you need to make sure no one else is messing with your process/thread signal mask behind your back.

Anything more *REALLY* needs a cut-down test case and a bug filed.

-- Terry
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-dev mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden


References: 
 >SIGPIPE and SIG_IGN (From: email@hidden)
 >Re: SIGPIPE and SIG_IGN (From: Glenn Anderson <email@hidden>)
 >Re: SIGPIPE and SIG_IGN (From: Terry Lambert <email@hidden>)
 >Re: SIGPIPE and SIG_IGN (From: Glenn Anderson <email@hidden>)

  • Prev by Date: Re: SIGPIPE and SIG_IGN
  • Next by Date: size of "disk cache"
  • Previous by thread: Re: SIGPIPE and SIG_IGN
  • Next by thread: size of "disk cache"
  • Index(es):
    • Date
    • Thread