Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does POSIX guarantee signals will not be delivered to a partially-initialized thread?

On most implementations of POSIX threads, some initialization is required in the newly-created thread before it is in a consistent state able to run application code. This may involve unlocking locks in the thread structure, initializing the "thread register" in implementations that use one, initializing thread-local data (either compiler-level TLS or POSIX thread-specific data), etc. I can't find a clear guarantee that all of this initialization will be finished before the thread can receive any signals; the closest I can find is in 2.4.3:

The following table defines a set of functions that shall be async-signal-safe. Therefore, applications can invoke them, without restriction, from signal-catching functions:

...

Presumably, some of these functions (at least fork, which has to inspect global state established by the pthread_atfork function) depend on the thread being in a consistent, initialized state.

One thing that bothers me is that I've read much of the glibc/nptl source, and cannot find any explicit synchronization to prevent a signal from being handled by the newly-created thread before it's fully initialized. I would expect the thread calling pthread_create to block all signals before calling clone, and for the new thread to unblock them once initialization is finished, but I can't find any code to that effect nor do I see it in strace output.

like image 264
R.. GitHub STOP HELPING ICE Avatar asked Nov 19 '10 16:11

R.. GitHub STOP HELPING ICE


1 Answers

(I don't think that this is a real answer, but it is to big for a comment)

This is a very interesting question. I've looked through glibc code for pthread_create to see how it behaves and unless I'm totally missing something there doesn't seem to be any special behavior to stop this (such as blocking all signals before clone and unblocking them in the in the child after some setup {after recording the thread creation time and the C++ catch all exception handler is set up, which happens even in the C code} ).

I was expecting to find a comment that mentioned the possibility of this situation and maybe even a mention of what POSIX said to do (or a mention that it did not say what to do).

Perhaps you should always wrap pthread_create in code to block and restore signals, and start all thread functions with an unblock call.

This may very well be an over site in pthreads (or glibc or my understanding of the code).

like image 190
nategoose Avatar answered Nov 15 '22 12:11

nategoose