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