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