xref: /llvm-project/compiler-rt/test/lsan/TestCases/Linux/fork_threaded.cpp (revision 029b410df31afd6ea1aee9da6949c84b6db19112)
1*97ccf6b8SFangrui Song // Test that thread local data is handled correctly after forking without
2*97ccf6b8SFangrui Song // exec(). In this test leak checking is initiated from a non-main thread.
3*97ccf6b8SFangrui Song // RUN: %clangxx_lsan %s -o %t
4*97ccf6b8SFangrui Song // RUN: %run %t 2>&1
5*97ccf6b8SFangrui Song 
6*97ccf6b8SFangrui Song #include <assert.h>
7*97ccf6b8SFangrui Song #include <pthread.h>
8*97ccf6b8SFangrui Song #include <stdio.h>
9*97ccf6b8SFangrui Song #include <stdlib.h>
10*97ccf6b8SFangrui Song #include <sys/wait.h>
11*97ccf6b8SFangrui Song #include <unistd.h>
12*97ccf6b8SFangrui Song 
13*97ccf6b8SFangrui Song __thread void *thread_local_var;
14*97ccf6b8SFangrui Song 
exit_thread_func(void * arg)15*97ccf6b8SFangrui Song void *exit_thread_func(void *arg) {
16*97ccf6b8SFangrui Song   exit(0);
17*97ccf6b8SFangrui Song }
18*97ccf6b8SFangrui Song 
ExitFromThread()19*97ccf6b8SFangrui Song void ExitFromThread() {
20*97ccf6b8SFangrui Song   pthread_t tid;
21*97ccf6b8SFangrui Song   int res;
22*97ccf6b8SFangrui Song   res = pthread_create(&tid, 0, exit_thread_func, 0);
23*97ccf6b8SFangrui Song   assert(res == 0);
24*97ccf6b8SFangrui Song   pthread_join(tid, 0);
25*97ccf6b8SFangrui Song }
26*97ccf6b8SFangrui Song 
main()27*97ccf6b8SFangrui Song int main() {
28*97ccf6b8SFangrui Song   int status = 0;
29*97ccf6b8SFangrui Song   thread_local_var = malloc(1337);
30*97ccf6b8SFangrui Song   pid_t pid = fork();
31*97ccf6b8SFangrui Song   assert(pid >= 0);
32*97ccf6b8SFangrui Song   if (pid > 0) {
33*97ccf6b8SFangrui Song     waitpid(pid, &status, 0);
34*97ccf6b8SFangrui Song     assert(WIFEXITED(status));
35*97ccf6b8SFangrui Song     return WEXITSTATUS(status);
36*97ccf6b8SFangrui Song   } else {
37*97ccf6b8SFangrui Song     // Spawn a thread and call exit() from there, to check that we track main
38*97ccf6b8SFangrui Song     // thread's pid correctly even if leak checking is initiated from another
39*97ccf6b8SFangrui Song     // thread.
40*97ccf6b8SFangrui Song     ExitFromThread();
41*97ccf6b8SFangrui Song   }
42*97ccf6b8SFangrui Song   return 0;
43*97ccf6b8SFangrui Song }
44