talking to stsp, he reminded me of a problematic bug that took some time to
track down in some desktop software that shall not be named. after a program
calls fork(), the child has only a single thread. per the standard, it needs
to get to exec() as quickly as possible. per the quality standards of modern
software, this doesn't always happen, and then strangeness happens.

this adds a quick check for this error condition. after a fork, we set a new
variable in the child that we are post threaded. this can be checked elsewhere
in the library. i added a check to pthread_join because that's a notable
problem function.


Index: rthread.c
===================================================================
RCS file: /cvs/src/lib/librthread/rthread.c,v
retrieving revision 1.94
diff -u -p -r1.94 rthread.c
--- rthread.c   4 Sep 2016 10:13:35 -0000       1.94
+++ rthread.c   30 May 2017 07:43:12 -0000
@@ -64,6 +64,7 @@ REDIRECT_SYSCALL(thrkill);
 static int concurrency_level;  /* not used */
 
 int _threads_ready;
+int _post_threaded;
 size_t _thread_pagesize;
 struct listhead _thread_list = LIST_HEAD_INITIALIZER(_thread_list);
 _atomic_lock_t _thread_lock = _SPINLOCK_UNLOCKED;
@@ -358,6 +359,11 @@ pthread_join(pthread_t thread, void **re
        pthread_t self;
        PREP_CANCEL_POINT(tib);
 
+       if (_post_threaded) {
+#define GREATSCOTT "great scott! serious repurcussions on future events!\n"
+               write(2, GREATSCOTT, sizeof(GREATSCOTT));
+               abort();
+       }
        if (!_threads_ready)
                _rthread_init();
        self = tib->tib_thread;
Index: rthread_fork.c
===================================================================
RCS file: /cvs/src/lib/librthread/rthread_fork.c,v
retrieving revision 1.19
diff -u -p -r1.19 rthread_fork.c
--- rthread_fork.c      4 Sep 2016 10:13:35 -0000       1.19
+++ rthread_fork.c      30 May 2017 07:41:29 -0000
@@ -58,6 +58,7 @@ _dofork(pid_t (*sys_fork)(void))
        pthread_t me;
        pid_t newid;
        int i;
+       extern int _post_threaded;
 
        if (!_threads_ready)
                return sys_fork();
@@ -110,6 +111,7 @@ _dofork(pid_t (*sys_fork)(void))
 
                /* single threaded now */
                __isthreaded = 0;
+               _post_threaded = 1;
        }
 #ifndef NO_PIC
        else if (_DYNAMIC)

Reply via email to