19 * This reproduces and issue if we get a signal after the pthread_atfork()
20 * prepare function of socket wrapper has been called.
22 * The order how pthread_atfork() handlers are set up is:
24 * -> preloaded libraries
27 * We have a library called thread_deadlock.
29 * This library registers a thread_deadlock_prepare() function via
32 * So pthread_atfork() registers the prepare function in the follow order:
33 * -> swrap_thread_prepare()
34 * -> thread_deadlock_prepare()
36 * In this test we fork and the swrap_thread_prepare() locks the mutex for
38 * Then thread_deadlock_prepare() is called which sends a signal to the parent
39 * process of this test. The signal triggers the signal handler below.
41 * When we call write() in the signal handler, we will try to bind the libc symbol
42 * and want to lock the symbol binding mutex. As it is already locked we run into
46 static void test_swrap_signal_handler(int signum)
49 fprintf(stderr, "PID: %u, SIGNUM: %d\n", (unsigned int)getpid(), signum);
50 w = write(1, "DEADLOCK?\n", 10);
51 fprintf(stderr, "WRITE: %zu\n", w);
54 static void test_swrap_fork_pthread(void **state)
57 struct sigaction act = {
58 .sa_handler = test_swrap_signal_handler,
62 (void)state; /* unused */
64 sigemptyset(&act.sa_mask);
65 sigaction(SIGUSR1, &act, NULL);
68 assert_return_code(pid, errno);
80 child_pid = waitpid(-1, &wstatus, 0);
81 assert_return_code(child_pid, errno);
83 assert_true(WIFEXITED(wstatus));
85 assert_int_equal(WEXITSTATUS(wstatus), 0);
93 const struct CMUnitTest swrap_tests[] = {
94 cmocka_unit_test(test_swrap_fork_pthread),
97 rc = cmocka_run_group_tests(swrap_tests, NULL, NULL);