1// Test that out-of-scope local variables are ignored by LSan.
2
3// LSan-in-ASan fails at -O0 on aarch64, because the stack use-after-return
4// instrumentation stashes the argument to `PutPointerOnStaleStack` on the stack
5// in order to conditionally call __asan_stack_malloc. This subverts our
6// expectations for this test, where we assume the pointer is never stashed
7// except at the bottom of the dead frame. Building at -O1 or greater solves
8// this problem, because the compiler is smart enough to stash the argument in a
9// callee-saved register for rematerialization instead.
10// RUN: %clangxx_lsan -O1 %s -o %t
11
12// RUN: %env_lsan_opts="report_objects=1:use_registers=0:use_stacks=1" not %run %t 2>&1 | FileCheck %s
13// RUN: %env_lsan_opts="report_objects=1:use_registers=0:use_stacks=1:exitcode=0" %run %t 2>&1 | FileCheck --check-prefix=CHECK-sanity %s
14//
15// x86 passes parameters through stack that may lead to false negatives
16// The same applies to s390x register save areas.
17// UNSUPPORTED: i686,target={{(x86|powerpc64|arm|s390x).*}}
18
19#include <stdio.h>
20#include <stdlib.h>
21#include "sanitizer_common/print_address.h"
22
23void **pp;
24
25// Put pointer far enough on the stack that LSan has space to run in without
26// overwriting it.
27// Hopefully the argument p will be passed on a register, saving us from false
28// negatives.
29__attribute__((noinline))
30void *PutPointerOnStaleStack(void *p) {
31 void *locals[2048];
32 locals[0] = p;
33 pp = &locals[0];
34 print_address("Test alloc: ", 1, locals[0]);
35 return 0;
36}
37
38int main() {
39 PutPointerOnStaleStack(p: malloc(size: 1337));
40 return 0;
41}
42
43// This must run after LSan, to ensure LSan didn't overwrite the pointer before
44// it had a chance to see it. If LSan is invoked with atexit(), this works.
45// Otherwise, we need a different method.
46__attribute__((destructor))
47__attribute__((no_sanitize_address))
48__attribute__((no_sanitize("hwaddress")))
49void ConfirmPointerHasSurvived() {
50 print_address("Value after LSan: ", 1, *pp);
51}
52// CHECK: Test alloc: [[ADDR:0x[0-9,a-f]+]]
53// CHECK-sanity: Test alloc: [[ADDR:0x[0-9,a-f]+]]
54// CHECK: LeakSanitizer: detected memory leaks
55// CHECK: [[ADDR]] (1337 bytes)
56// CHECK: SUMMARY: {{.*}}Sanitizer:
57// CHECK-sanity: Value after LSan: [[ADDR]]
58

source code of compiler-rt/test/lsan/TestCases/stale_stack_leak.cpp