xref: /llvm-project/compiler-rt/test/lsan/TestCases/create_thread_leak.cpp (revision e51fc36c385d756ccbc2be8c47c52af207c3aead)
1 // Test handling of arg and retval of child thread.
2 
3 // RUN: %clangxx_lsan -pthread %s -o %t
4 // RUN: not %run %t 10 1 0 0 2>&1 | FileCheck %s --check-prefixes=LEAK,LEAK123
5 // RUN: not %run %t 10 0 1 0 2>&1 | FileCheck %s --check-prefixes=LEAK,LEAK234
6 // RUN: not %run %t 10 0 0 1 2>&1 | FileCheck %s --check-prefixes=LEAK,LEAK234
7 // RUN: %run %t 10 0 0 0
8 
9 // This test appears to be flaky on x86_64-darwin buildbots.
10 // UNSUPPORTED: darwin
11 
12 #include <pthread.h>
13 #include <stdlib.h>
14 
15 #include <sanitizer/lsan_interface.h>
16 
17 int detach;
18 int leak_arg;
19 int leak_retval;
20 
21 static void *thread_free(void *args) {
22   if (!leak_arg)
23     free(args);
24   return malloc(234);
25 }
26 
27 int main(int argc, char **argv) {
28   int n = atoi(argv[1]);
29   leak_arg = atoi(argv[2]);
30   leak_retval = atoi(argv[3]);
31   detach = atoi(argv[4]);
32   for (int i = 0; i < n; ++i) {
33     pthread_t threads[10];
34 
35     for (auto &thread : threads) {
36       pthread_create(&thread, 0, thread_free, malloc(123));
37       if (__lsan_do_recoverable_leak_check())
38         return 1;
39     }
40 
41     for (auto &thread : threads) {
42       if (detach) {
43         pthread_detach(thread);
44         continue;
45       }
46       void *retval = 0;
47       pthread_join(thread, &retval);
48       if (!leak_retval)
49         free(retval);
50     }
51   }
52   return 0;
53 }
54 
55 // LEAK: LeakSanitizer: detected memory leaks
56 // LEAK123: in main
57 // LEAK234: in thread_free
58