Bug 115211 - pthread_atfork misbehaves in initial thread
Summary: pthread_atfork misbehaves in initial thread
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: threads (show other bugs)
Version: 6.2-RELEASE
Hardware: Any Any
: Normal Affects Only Me
Assignee: freebsd-threads (Nobody)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-08-05 10:40 UTC by Douglas Wells
Modified: 2015-05-15 16:15 UTC (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Douglas Wells 2007-08-05 10:40:01 UTC
	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.

Fix: 

Fix and/or workaround unknown (other than to execute from
	a created thread).
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 --------------------
Comment 1 Craig Rodrigues 2007-08-24 13:41:56 UTC
Hi,

On FreeBSD-CURRENT, if I do:

gcc pthread_atforkbug.c -lkse && ./a.out

This is the output:

parent pid (48871)
Child exiting: (48872)
child (48872) returned

If I do:

gcc pthread_atforkbug.c -lkse && ./a.out

parent pid (48877)
af_prepare:  pid (48877)
 af_parent:  pid (48877)
  af_child:  pid (48878)
Child exiting: (48878)
child (48878) returned


On FreeBSD 6.2, -pthread is mapped to -lkse, while on CURRENT, it is mapped
to -lthr.  Can you try your test again with -lthr on FreeBSD 6.2?
This looks like a libkse bug.

-- 
Craig Rodrigues
rodrigc@crodrigues.org
Comment 2 Douglas Wells 2007-08-27 13:46:52 UTC
> Hi,
> 
> On FreeBSD-CURRENT, if I do:
> 
> gcc pthread_atforkbug.c -lkse && ./a.out
> 
> This is the output:
> 
> parent pid (48871)
> Child exiting: (48872)
> child (48872) returned
> 
> If I do:
> 
> gcc pthread_atforkbug.c -lkse && ./a.out
> 
> parent pid (48877)
> af_prepare:  pid (48877)
>  af_parent:  pid (48877)
>   af_child:  pid (48878)
> Child exiting: (48878)
> child (48878) returned
> 
> 
> On FreeBSD 6.2, -pthread is mapped to -lkse, while on CURRENT, it is mapped
> to -lthr.  Can you try your test again with -lthr on FreeBSD 6.2?
> This looks like a libkse bug.
> 
> -- 
> Craig Rodrigues
> rodrigc@crodrigues.org

Yes, I can verify that using:
	-pthread => erroneous behavior
	-lthr => expected behavior
on my installation of 6.2.

 - dmw