Safely recognize when fork is running from main thread or another pthread

* child_info.h (struct child_info): Add member from_main.
        * fork.cc (frok::child): Check from_main rather than stackaddr.
        (frok::parent): Set ch.from_main if running in the main thread.

Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
Corinna Vinschen 2015-12-03 12:38:19 +01:00
parent 8974e06da3
commit 89e86492b3
3 changed files with 10 additions and 2 deletions

View File

@ -1,3 +1,9 @@
2015-12-03 Corinna Vinschen <corinna@vinschen.de>
* child_info.h (struct child_info): Add member from_main.
* fork.cc (frok::child): Check from_main rather than stackaddr.
(frok::parent): Set ch.from_main if running in the main thread.
2015-12-02 Corinna Vinschen <corinna@vinschen.de> 2015-12-02 Corinna Vinschen <corinna@vinschen.de>
* child_info.h (CURR_CHILD_INFO_MAGIC): Align to below change. * child_info.h (CURR_CHILD_INFO_MAGIC): Align to below change.

View File

@ -39,7 +39,7 @@ enum child_status
#define EXEC_MAGIC_SIZE sizeof(child_info) #define EXEC_MAGIC_SIZE sizeof(child_info)
/* Change this value if you get a message indicating that it is out-of-sync. */ /* Change this value if you get a message indicating that it is out-of-sync. */
#define CURR_CHILD_INFO_MAGIC 0xc96f5e9U #define CURR_CHILD_INFO_MAGIC 0x30ea98f6U
#define NPROCS 256 #define NPROCS 256
@ -109,6 +109,7 @@ public:
void *stackbase; // StackBase of parent thread void *stackbase; // StackBase of parent thread
size_t guardsize; // size of POSIX guard region or (size_t) -1 if size_t guardsize; // size of POSIX guard region or (size_t) -1 if
// user stack // user stack
bool from_main; // true if started from parent's main thread
char filler[4]; char filler[4];
child_info_fork (); child_info_fork ();
void __reg1 handle_fork (); void __reg1 handle_fork ();

View File

@ -149,7 +149,7 @@ frok::child (volatile char * volatile here)
/* If we've played with the stack, stacksize != 0. That means that /* If we've played with the stack, stacksize != 0. That means that
fork() was invoked from other than the main thread. Make sure that fork() was invoked from other than the main thread. Make sure that
the threadinfo information is properly set up. */ the threadinfo information is properly set up. */
if (fork_info->stackaddr) if (!fork_info->from_main)
{ {
_main_tls = &_my_tls; _main_tls = &_my_tls;
_main_tls->init_thread (NULL, NULL); _main_tls->init_thread (NULL, NULL);
@ -307,6 +307,7 @@ frok::parent (volatile char * volatile stack_here)
ch.forker_finished = forker_finished; ch.forker_finished = forker_finished;
ch.from_main = &_my_tls == _main_tls;
ch.stackbase = NtCurrentTeb()->Tib.StackBase; ch.stackbase = NtCurrentTeb()->Tib.StackBase;
ch.stackaddr = NtCurrentTeb ()->DeallocationStack; ch.stackaddr = NtCurrentTeb ()->DeallocationStack;
if (!ch.stackaddr) if (!ch.stackaddr)