threads/119920: fork broken in libpthread
Daniel Eischen
deischen at freebsd.org
Thu Jan 24 07:08:21 PST 2008
On Thu, 24 Jan 2008, Julian Elischer wrote:
> Gary Stanley wrote:
>> The following reply was made to PR threads/119920; it has been noted by
>> GNATS.
>>
>> From: Gary Stanley <gary at velocity-servers.net>
>> To: bug-followup at FreeBSD.org
>> Cc: Subject: Re: threads/119920: fork broken in libpthread
>> Date: Thu, 24 Jan 2008 03:24:47 -0500
>>
>> I also have this problem, see threads/118715
>> I was able to grab some ktrace info, but most of the time the process is
>> stuck, and ktrace doesn't display any data.
>> _______________________________________________
>> freebsd-threads at freebsd.org mailing list
>> http://lists.freebsd.org/mailman/listinfo/freebsd-threads
>> To unsubscribe, send any mail to "freebsd-threads-unsubscribe at freebsd.org"
>
> dan what IS the fix for this? I assume you must have fixed it in -current/7
You want cvs diff -u -r1.126 -r1.128 src/lib/libkse/thread/thr_kern.c.
The WARNS'ify diffs are not necessary, so it should look something
like shown below. Probably an MFC of all of libkse (minus jasone's
malloc changes) should be done to -7 and -6.
--
DE
Index: thr_kern.c
===================================================================
RCS file: /opt/FreeBSD/cvs/src/lib/libkse/thread/thr_kern.c,v
retrieving revision 1.126
retrieving revision 1.128
diff -u -r1.126 -r1.128
--- thr_kern.c 27 Nov 2007 03:16:44 -0000 1.126
+++ thr_kern.c 6 Dec 2007 06:04:01 -0000 1.128
@@ -342,6 +342,16 @@
_LCK_SET_PRIVATE2(&curthread->kse->k_lockusers[i], NULL);
}
curthread->kse->k_locklevel = 0;
+
+ /*
+ * Reinitialize the thread and signal locks so that
+ * sigaction() will work after a fork().
+ */
+ _lock_reinit(&curthread->lock, LCK_ADAPTIVE, _thr_lock_wait,
+ _thr_lock_wakeup);
+ _lock_reinit(&_thread_signal_lock, LCK_ADAPTIVE, _kse_lock_wait,
+ _kse_lock_wakeup);
+
_thr_spinlock_init();
if (__isthreaded) {
_thr_rtld_fini();
@@ -351,6 +361,19 @@
curthread->kse->k_kcb->kcb_kmbx.km_curthread = NULL;
curthread->attr.flags |= PTHREAD_SCOPE_SYSTEM;
+ /*
+ * After a fork, it is possible that an upcall occurs in
+ * the parent KSE that fork()'d before the child process
+ * is fully created and before its vm space is copied.
+ * During the upcall, the tcb is set to null or to another
+ * thread, and this is what gets copied in the child process
+ * when the vm space is cloned sometime after the upcall
+ * occurs. Note that we shouldn't have to set the kcb, but
+ * we do it for completeness.
+ */
+ _kcb_set(curthread->kse->k_kcb);
+ _tcb_set(curthread->kse->k_kcb, curthread->tcb);
+
/* After a fork(), there child should have no pending signals. */
sigemptyset(&curthread->sigpend);
More information about the freebsd-threads
mailing list