197ccf6b8SFangrui Song // Test that stacks of non-main threads are included in the root set. 297ccf6b8SFangrui Song // RUN: %clangxx_lsan -pthread %s -o %t 3*d08e5d4cSClemens Wasser // RUN: %env_lsan_opts="report_objects=1:use_registers=0:use_stacks=0" not %run %t 2>&1 | FileCheck %s 4*d08e5d4cSClemens Wasser // RUN: %env_lsan_opts="report_objects=1:use_registers=0:use_stacks=1" %run %t 2>&1 597ccf6b8SFangrui Song // RUN: %env_lsan_opts="" %run %t 2>&1 697ccf6b8SFangrui Song 797ccf6b8SFangrui Song #include <assert.h> 897ccf6b8SFangrui Song #include <pthread.h> 997ccf6b8SFangrui Song #include <sched.h> 1097ccf6b8SFangrui Song #include <stdio.h> 1197ccf6b8SFangrui Song #include <stdlib.h> 1297ccf6b8SFangrui Song #include "sanitizer_common/print_address.h" 1397ccf6b8SFangrui Song 1497ccf6b8SFangrui Song extern "C" stacks_thread_func(void * arg)1597ccf6b8SFangrui Songvoid *stacks_thread_func(void *arg) { 1697ccf6b8SFangrui Song int *sync = reinterpret_cast<int *>(arg); 1797ccf6b8SFangrui Song void *p = malloc(1337); 1897ccf6b8SFangrui Song print_address("Test alloc: ", 1, p); 1997ccf6b8SFangrui Song fflush(stderr); 2097ccf6b8SFangrui Song __sync_fetch_and_xor(sync, 1); 2197ccf6b8SFangrui Song while (true) 2297ccf6b8SFangrui Song sched_yield(); 2397ccf6b8SFangrui Song } 2497ccf6b8SFangrui Song main()2597ccf6b8SFangrui Songint main() { 2697ccf6b8SFangrui Song int sync = 0; 2797ccf6b8SFangrui Song pthread_t thread_id; 2897ccf6b8SFangrui Song int res = pthread_create(&thread_id, 0, stacks_thread_func, &sync); 2997ccf6b8SFangrui Song assert(res == 0); 3097ccf6b8SFangrui Song while (!__sync_fetch_and_xor(&sync, 0)) 3197ccf6b8SFangrui Song sched_yield(); 3297ccf6b8SFangrui Song return 0; 3397ccf6b8SFangrui Song } 3497ccf6b8SFangrui Song // CHECK: Test alloc: [[ADDR:0x[0-9,a-f]+]] 3597ccf6b8SFangrui Song // CHECK: LeakSanitizer: detected memory leaks 3697ccf6b8SFangrui Song // CHECK: [[ADDR]] (1337 bytes) 3797ccf6b8SFangrui Song // CHECK: SUMMARY: {{(Leak|Address)}}Sanitizer: 38