1 /* Check if pthread_atfork handler can call dlclose (BZ#24595).
2 Copyright (C) 2022-2023 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
25 #include <support/check.h>
26 #include <support/xthread.h>
27 #include <support/capture_subprocess.h>
28 #include <support/xdlfcn.h>
30 /* Check if pthread_atfork handlers do not deadlock when calling a function
31 that might alter the internal fork handle list, such as dlclose.
33 The test registers a callback set with pthread_atfork(), dlopen() a shared
34 library (nptl/tst-atfork3mod.c), calls an exported symbol from the library
35 (which in turn also registers atfork handlers), and calls fork to trigger
39 static bool run_dlclose_prepare
;
40 static bool run_dlclose_parent
;
41 static bool run_dlclose_child
;
46 if (run_dlclose_prepare
)
53 if (run_dlclose_parent
)
60 if (run_dlclose_child
)
65 proc_func (void *closure
)
70 do_test_generic (bool dlclose_prepare
, bool dlclose_parent
, bool dlclose_child
)
72 run_dlclose_prepare
= dlclose_prepare
;
73 run_dlclose_parent
= dlclose_parent
;
74 run_dlclose_child
= dlclose_child
;
76 handler
= xdlopen ("tst-atfork3mod.so", RTLD_NOW
);
78 int (*atfork3mod_func
)(void);
79 atfork3mod_func
= xdlsym (handler
, "atfork3mod_func");
83 struct support_capture_subprocess proc
84 = support_capture_subprocess (proc_func
, NULL
);
85 support_capture_subprocess_check (&proc
, "tst-atfork3", 0, sc_allow_none
);
87 handler
= atfork3mod_func
= NULL
;
89 support_capture_subprocess_free (&proc
);
93 thread_func (void *closure
)
102 /* Make the process acts as multithread. */
104 xpthread_attr_init (&attr
);
105 xpthread_attr_setdetachstate (&attr
, PTHREAD_CREATE_DETACHED
);
106 xpthread_create (&attr
, thread_func
, NULL
);
109 TEST_COMPARE (pthread_atfork (prepare
, parent
, child
), 0);
111 do_test_generic (true /* prepare */, false /* parent */, false /* child */);
112 do_test_generic (false /* prepare */, true /* parent */, false /* child */);
113 do_test_generic (false /* prepare */, false /* parent */, true /* child */);
118 #include <support/test-driver.c>