1// Test handling of arg and retval of child thread.
2
3// RUN: %clangxx_lsan -pthread %s -o %t
4// RUN: %run not %t 10 1 0 0 2>&1 | FileCheck %s --check-prefixes=LEAK,LEAK123
5// RUN: %run not %t 10 0 1 0 2>&1 | FileCheck %s --check-prefixes=LEAK,LEAK234
6// RUN: %run not %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
17int detach;
18int leak_arg;
19int leak_retval;
20
21static void *thread_free(void *args) {
22 if (!leak_arg)
23 free(ptr: args);
24 return malloc(size: 234);
25}
26
27int main(int argc, char **argv) {
28 int n = atoi(nptr: argv[1]);
29 leak_arg = atoi(nptr: argv[2]);
30 leak_retval = atoi(nptr: argv[3]);
31 detach = atoi(nptr: argv[4]);
32 for (int i = 0; i < n; ++i) {
33 pthread_t threads[10];
34
35 for (auto &thread : threads) {
36 pthread_create(newthread: &thread, attr: 0, start_routine: thread_free, arg: malloc(size: 123));
37 if (__lsan_do_recoverable_leak_check())
38 return 1;
39 }
40
41 for (auto &thread : threads) {
42 if (detach) {
43 pthread_detach(th: thread);
44 continue;
45 }
46 void *retval = 0;
47 pthread_join(th: thread, thread_return: &retval);
48 if (!leak_retval)
49 free(ptr: retval);
50 }
51 }
52 return 0;
53}
54
55// LEAK: LeakSanitizer: detected memory leaks
56// LEAK123: in main
57// LEAK234: in thread_free
58

source code of compiler-rt/test/lsan/TestCases/create_thread_leak.cpp