Date: Sun, 5 Aug 2007 01:50:17 -0400 (EDT) From: Douglas Wells <sysmaint@contek.com> To: FreeBSD-gnats-submit@FreeBSD.org Cc: sysmaint@contek.com Subject: threads/115211: pthread_atfork misbehaves in initial thread Message-ID: <20070805055017.2646B3F407@mail.contek.com> Resent-Message-ID: <200708050940.l759e1cM010393@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 115211 >Category: threads >Synopsis: pthread_atfork misbehaves in initial thread >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-threads >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Sun Aug 05 09:40:01 GMT 2007 >Closed-Date: >Last-Modified: >Originator: Douglas Wells >Release: FreeBSD 6.2-RELEASE-p1 i386 >Organization: >Environment: System: FreeBSD flame.contek.com 6.2-RELEASE-p1 FreeBSD 6.2-RELEASE-p1 #0: Sun Feb 11 18:14:07 EST 2007 root@flame.contek.com:/other5/src.6.2/sys/i386/compile/FLAME.6.2 i386 Above system is patched up to SA-07:07.bind. Using default compiler: gcc version 3.4.6 [FreeBSD] 20060305. >Description: If pthread_atfork is invoked in the original thread of a process, it does *not* invoke the various handlers. If the same test is invoked from a created thread, it invokes the various handlers as expected. I don't see any exception in the POSIX standard that supports this, and the test program runs as expected on a recent OS/X. >How-To-Repeat: Use the included test program. If compiled and run as: "gcc -pthread atforkbug.c && ./a.out", example (erroneous) output is: parent pid (11263) Child exiting: (11264) child (11264) returned If compiled and run as: "gcc -DUSE_NEW_THREAD -pthread atforkbug.c && ./a.out", the program behaves as I expect: parent pid (11270) af_prepare: pid (11270) af_parent: pid (11270) af_child: pid (11271) Child exiting: (11271) child (11271) returned ------------------------- test program ---------------------- #include <stdlib.h> #include <stdio.h> #include <stdbool.h> #include <errno.h> #include <assert.h> #include <unistd.h> #include <pthread.h> #include <sys/types.h> #include <sys/wait.h> #if defined (USE_NEW_THREAD) bool run_in_separate_thread = true; #else bool run_in_separate_thread = false; #endif void af_prepare (void) { fprintf (stderr, "af_prepare: pid (%ld)\n", (long) getpid ()); } void af_parent (void) { fprintf (stderr, " af_parent: pid (%ld)\n", (long) getpid ()); } void af_child (void) { fprintf (stderr, " af_child: pid (%ld)\n", (long) getpid ()); } void * run_test (void *arg) { pid_t child, xpid; int err; (void) arg; err = pthread_atfork (af_prepare, af_parent, af_child); assert (err == 0); switch ((int) (child = fork ())) { case -1: assert (! "bad fork"); case 0: /* child here */ sleep (1); fprintf (stderr, "Child exiting: (%ld)\n", (long) getpid ()); exit (EXIT_SUCCESS); default: xpid = waitpid (child, NULL, 0); assert (xpid == child); fprintf (stdout, "child (%ld) returned\n", (long) child); } return NULL; } int main (void) { fprintf (stdout, "parent pid (%ld)\n", (long) getpid ()); if (run_in_separate_thread) { pthread_t tid; int err; err = pthread_create (&tid, NULL, run_test, NULL); assert (err == 0); err = pthread_join (tid, NULL); assert (err == 0); } else run_test (NULL); return EXIT_SUCCESS; } ----------------------- end test program -------------------- >Fix: Fix and/or workaround unknown (other than to execute from a created thread). >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20070805055017.2646B3F407>