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 // The same applies to s390x register save areas.
9 // UNSUPPORTED: x86,i686,powerpc64,arm,s390x
10
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include "sanitizer_common/print_address.h"
14
15 void **pp;
16
17 // Put pointer far enough on the stack that LSan has space to run in without
18 // overwriting it.
19 // Hopefully the argument p will be passed on a register, saving us from false
20 // negatives.
21 __attribute__((noinline))
PutPointerOnStaleStack(void * p)22 void *PutPointerOnStaleStack(void *p) {
23 void *locals[2048];
24 locals[0] = p;
25 pp = &locals[0];
26 print_address("Test alloc: ", 1, locals[0]);
27 return 0;
28 }
29
main()30 int main() {
31 PutPointerOnStaleStack(malloc(1337));
32 return 0;
33 }
34
35 // This must run after LSan, to ensure LSan didn't overwrite the pointer before
36 // it had a chance to see it. If LSan is invoked with atexit(), this works.
37 // Otherwise, we need a different method.
38 __attribute__((destructor))
39 __attribute__((no_sanitize_address))
ConfirmPointerHasSurvived()40 void ConfirmPointerHasSurvived() {
41 print_address("Value after LSan: ", 1, *pp);
42 }
43 // CHECK: Test alloc: [[ADDR:0x[0-9,a-f]+]]
44 // CHECK-sanity: Test alloc: [[ADDR:0x[0-9,a-f]+]]
45 // CHECK: LeakSanitizer: detected memory leaks
46 // CHECK: [[ADDR]] (1337 bytes)
47 // CHECK: SUMMARY: {{(Leak|Address)}}Sanitizer:
48 // CHECK-sanity: Value after LSan: [[ADDR]]
49