1 // Test that out-of-scope local variables are ignored by LSan.
2 // RUN: LSAN_BASE="report_objects=1:use_registers=0:use_stacks=1"
3 // RUN: %clangxx_lsan %s -o %t
4 // RUN: %env_lsan_opts=$LSAN_BASE not %run %t 2>&1 | FileCheck %s
5 // RUN: %env_lsan_opts=$LSAN_BASE":exitcode=0" %run %t 2>&1 | FileCheck --check-prefix=CHECK-sanity %s
6 //
7 // x86 passes parameters through stack that may lead to false negatives
8 // UNSUPPORTED: x86,powerpc64
9 
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include "sanitizer_common/print_address.h"
13 
14 void **pp;
15 
16 // Put pointer far enough on the stack that LSan has space to run in without
17 // overwriting it.
18 // Hopefully the argument p will be passed on a register, saving us from false
19 // negatives.
20 __attribute__((noinline))
21 void *PutPointerOnStaleStack(void *p) {
22   void *locals[2048];
23   locals[0] = p;
24   pp = &locals[0];
25   print_address("Test alloc: ", 1, locals[0]);
26   return 0;
27 }
28 
29 int main() {
30   PutPointerOnStaleStack(malloc(1337));
31   return 0;
32 }
33 
34 // This must run after LSan, to ensure LSan didn't overwrite the pointer before
35 // it had a chance to see it. If LSan is invoked with atexit(), this works.
36 // Otherwise, we need a different method.
37 __attribute__((destructor))
38 __attribute__((no_sanitize_address))
39 void ConfirmPointerHasSurvived() {
40   print_address("Value after LSan: ", 1, *pp);
41 }
42 // CHECK: Test alloc: [[ADDR:0x[0-9,a-f]+]]
43 // CHECK-sanity: Test alloc: [[ADDR:0x[0-9,a-f]+]]
44 // CHECK: LeakSanitizer: detected memory leaks
45 // CHECK: [[ADDR]] (1337 bytes)
46 // CHECK: SUMMARY: {{(Leak|Address)}}Sanitizer:
47 // CHECK-sanity: Value after LSan: [[ADDR]]
48