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