On Tue, May 30, 2017 at 03:48:06AM -0400, Ted Unangst wrote: > 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)); ^^^^^^^^^^^^^^^^^^ maybe sizeof(GREATSCOTT)-1
-pk > + 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) >