1 // Test that registers of running threads are included in the root set. 2 // RUN: LSAN_BASE="report_objects=1:use_stacks=0" 3 // RUN: %clangxx_lsan -pthread %s -o %t 4 // RUN: %env_lsan_opts=$LSAN_BASE:"use_registers=0" not %run %t 2>&1 | FileCheck %s 5 // RUN: %env_lsan_opts=$LSAN_BASE:"use_registers=1" %run %t 2>&1 6 // RUN: %env_lsan_opts="" %run %t 2>&1 7 8 #include "sanitizer_common/print_address.h" 9 #include <assert.h> 10 #include <pthread.h> 11 #include <sched.h> 12 #include <stdio.h> 13 #include <stdlib.h> 14 15 extern "C" void *registers_thread_func(void *arg) { 16 int *sync = reinterpret_cast<int *>(arg); 17 void *p = malloc(1337); 18 print_address("Test alloc: ", 1, p); 19 fflush(stderr); 20 21 // To store the pointer, choose a register which is unlikely to be reused by 22 // a function call. 23 #if defined(__i386__) || defined(__i686__) 24 asm("mov %0, %%edi" 25 : 26 : "r"(p)); 27 #elif defined(__x86_64__) 28 asm("mov %0, %%r15" 29 : 30 : "r"(p)); 31 #elif defined(__mips__) 32 asm("move $16, %0" 33 : 34 : "r"(p)); 35 #elif defined(__arm__) 36 asm("mov r5, %0" 37 : 38 : "r"(p)); 39 #elif defined(__aarch64__) 40 // x9-10are used. x11-12 are probably used. 41 // So we pick x13 to be safe. 42 asm("mov x13, %0" 43 : 44 : "r"(p)); 45 #elif defined(__powerpc__) 46 asm("mr 30, %0" 47 : 48 : "r"(p)); 49 #elif defined(__s390x__) 50 asm("lgr %%r10, %0" 51 : 52 : "r"(p)); 53 #elif defined(__riscv) 54 asm("mv s11, %0" 55 : 56 : "r"(p)); 57 #else 58 #error "Test is not supported on this architecture." 59 #endif 60 __sync_fetch_and_xor(sync, 1); 61 while (true) 62 sched_yield(); 63 } 64 65 int main() { 66 int sync = 0; 67 pthread_t thread_id; 68 int res = pthread_create(&thread_id, 0, registers_thread_func, &sync); 69 assert(res == 0); 70 while (!__sync_fetch_and_xor(&sync, 0)) 71 sched_yield(); 72 return 0; 73 } 74 // CHECK: Test alloc: [[ADDR:0x[0-9,a-f]+]] 75 // CHECK: LeakSanitizer: detected memory leaks 76 // CHECK: [[ADDR]] (1337 bytes) 77 // CHECK: SUMMARY: {{(Leak|Address)}}Sanitizer: 78