1// Test for threads spawned with wqthread_start 2// RUN: LSAN_BASE="report_objects=1:use_stacks=0:use_registers=0" 3// RUN: %clangxx_lsan %s -DDISPATCH_ASYNC -o %t-async -framework Foundation 4// RUN: %clangxx_lsan %s -DDISPATCH_SYNC -o %t-sync -framework Foundation 5// RUN: %env_lsan_opts=$LSAN_BASE not %run %t-async 2>&1 | FileCheck %s 6// RUN: %env_lsan_opts=$LSAN_BASE not %run %t-sync 2>&1 | FileCheck %s 7 8#include <dispatch/dispatch.h> 9#include <pthread.h> 10#include <stdlib.h> 11 12#include "sanitizer_common/print_address.h" 13 14bool done = false; 15 16void worker_do_leak(int size) { 17 void *p = malloc(size); 18 print_address("Test alloc: ", 1, p); 19 done = true; 20} 21 22#if DISPATCH_ASYNC 23// Tests for the Grand Central Dispatch. See 24// http://developer.apple.com/library/mac/#documentation/Performance/Reference/GCD_libdispatch_Ref/Reference/reference.html 25// for the reference. 26void TestGCDDispatch() { 27 dispatch_queue_t queue = dispatch_get_global_queue(0, 0); 28 dispatch_block_t block = ^{ 29 worker_do_leak(1337); 30 }; 31 // dispatch_async() runs the task on a worker thread that does not go through 32 // pthread_create(). We need to verify that LeakSanitizer notices that the 33 // thread has started. 34 dispatch_async(queue, block); 35 while (!done) 36 pthread_yield_np(); 37} 38#elif DISPATCH_SYNC 39void TestGCDDispatch() { 40 dispatch_queue_t queue = dispatch_get_global_queue(2, 0); 41 dispatch_block_t block = ^{ 42 worker_do_leak(1337); 43 }; 44 // dispatch_sync() runs the task on a worker thread that does not go through 45 // pthread_create(). We need to verify that LeakSanitizer notices that the 46 // thread has started. 47 dispatch_sync(queue, block); 48} 49#endif 50 51int main() { 52 TestGCDDispatch(); 53 return 0; 54} 55 56// CHECK: Test alloc: [[addr:0x[0-9,a-f]+]] 57// CHECK: LeakSanitizer: detected memory leaks 58// CHECK: [[addr]] (1337 bytes) 59// CHECK: SUMMARY: {{(Leak|Address)}}Sanitizer: 60