From owner-freebsd-stable@FreeBSD.ORG Mon Oct 5 23:48:56 2009 Return-Path: Delivered-To: freebsd-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 83DE1106566B for ; Mon, 5 Oct 2009 23:48:56 +0000 (UTC) (envelope-from matthew.fleming@isilon.com) Received: from seaxch09.isilon.com (seaxch09.isilon.com [74.85.160.25]) by mx1.freebsd.org (Postfix) with ESMTP id 6C21B8FC0C for ; Mon, 5 Oct 2009 23:48:56 +0000 (UTC) x-mimeole: Produced By Microsoft Exchange V6.5 Content-class: urn:content-classes:message MIME-Version: 1.0 Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: quoted-printable Date: Mon, 5 Oct 2009 16:48:55 -0700 Message-ID: <06D5F9F6F655AD4C92E28B662F7F853E03217DCE@seaxch09.desktop.isilon.com> X-MS-Has-Attach: X-MS-TNEF-Correlator: Thread-Topic: libthr and daemon() Thread-Index: AcpGFmYgHqq4lT7VQTO38LEndzavEQ== From: "Matthew Fleming" To: Subject: libthr and daemon() X-BeenThere: freebsd-stable@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Production branch of FreeBSD source code List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 05 Oct 2009 23:48:56 -0000 I have some code that tries to use pthread_cond_wait() and it's getting back EPERM. Upon further investigation, here's what I've found: When the app starts, libthr's _libpthread_init calls init_main_thread() to set the thread id in struct pthread's tid. The app opens a log file then calls daemon(). daemon() calls fork() fork() does not appear to be linked to _fork() in libthr; see below. The app creates a thread to handle signals. The app attempts to wait on a condition variable (pthread_cond_wait(); this gives EPERM). Looking into libthr's cond_wait_common(), it does a THR_UMUTEX_LOCK on the cv's c_lock using the struct pthread from _get_curthread(). Here, curthread points to the pthread struct that got the tid from thr_self on startup. Because of fork() this is the same address in the daemonized app as the original. But curthread->tid is the tid of the original app, not the daemonized version, hence my assumption that fork() didn't resolve to libthr's _fork(). When cond_wait_common() calls into the kernel to actually do the cv_wait, do_unlock_umutex/do_unlock_normal() returns EPERM since the tid does not match. AFAICT this has nothing to do with any code in the app itself. The two things I don't know: 1) what utilities can I use to show me which version of fork will be used at runtime? ldd just shows me that the app is linked against libc and libthr. 2) why would fork resolve to the one in libc (presumably, I'm not sure how to prove this) instead of the one in libthr? Thanks, matthew