12d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// RUN: export ASAN_OPTIONS=detect_stack_use_after_return=1 26a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines// RUN: %clangxx_asan -O0 %s -pthread -o %t && not %run %t 2>&1 | FileCheck %s 36a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines// RUN: %clangxx_asan -O1 %s -pthread -o %t && not %run %t 2>&1 | FileCheck %s 46a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines// RUN: %clangxx_asan -O2 %s -pthread -o %t && not %run %t 2>&1 | FileCheck %s 56a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines// RUN: %clangxx_asan -O3 %s -pthread -o %t && not %run %t 2>&1 | FileCheck %s 62d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=0 %run %t 72d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// Regression test for a CHECK failure with small stack size and large frame. 86a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines// RUN: %clangxx_asan -O3 %s -pthread -o %t -DkSize=10000 -DUseThread -DkStackSize=65536 && not %run %t 2>&1 | FileCheck --check-prefix=THREAD %s 92d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// 102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// Test that we can find UAR in a thread other than main: 116a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines// RUN: %clangxx_asan -DUseThread -O2 %s -pthread -o %t && not %run %t 2>&1 | FileCheck --check-prefix=THREAD %s 122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// 132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// Test the max_uar_stack_size_log/min_uar_stack_size_log flag. 142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// 152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:max_uar_stack_size_log=20:verbosity=1 not %run %t 2>&1 | FileCheck --check-prefix=CHECK-20 %s 162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:min_uar_stack_size_log=24:max_uar_stack_size_log=24:verbosity=1 not %run %t 2>&1 | FileCheck --check-prefix=CHECK-24 %s 172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include <stdio.h> 192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include <pthread.h> 202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#ifndef kSize 222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines# define kSize 1 232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif 242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#ifndef UseThread 262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines# define UseThread 0 272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif 282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#ifndef kStackSize 302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines# define kStackSize 0 312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif 322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines__attribute__((noinline)) 342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hineschar *Ident(char *x) { 352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines fprintf(stderr, "1: %p\n", x); 362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines return x; 372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines__attribute__((noinline)) 402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hineschar *Func1() { 412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines char local[kSize]; 422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines return Ident(local); 432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines__attribute__((noinline)) 462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid Func2(char *x) { 472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines fprintf(stderr, "2: %p\n", x); 482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines *x = 1; 492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // CHECK: WRITE of size 1 {{.*}} thread T0 502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // CHECK: #0{{.*}}Func2{{.*}}stack-use-after-return.cc:[[@LINE-2]] 512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // CHECK: is located in stack of thread T0 at offset 522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // CHECK: 'local' <== Memory access at offset {{16|32}} is inside this variable 532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // THREAD: WRITE of size 1 {{.*}} thread T{{[1-9]}} 542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // THREAD: #0{{.*}}Func2{{.*}}stack-use-after-return.cc:[[@LINE-6]] 552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // THREAD: is located in stack of thread T{{[1-9]}} at offset 562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // THREAD: 'local' <== Memory access at offset {{16|32}} is inside this variable 572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // CHECK-20: T0: FakeStack created:{{.*}} stack_size_log: 20 582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // CHECK-24: T0: FakeStack created:{{.*}} stack_size_log: 24 592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid *Thread(void *unused) { 622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines Func2(Func1()); 632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines return NULL; 642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 652d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesint main(int argc, char **argv) { 672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if UseThread 682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines pthread_attr_t attr; 692d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines pthread_attr_init(&attr); 702d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if (kStackSize > 0) 712d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines pthread_attr_setstacksize(&attr, kStackSize); 722d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines pthread_t t; 732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines pthread_create(&t, &attr, Thread, 0); 742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines pthread_attr_destroy(&attr); 752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines pthread_join(t, 0); 762d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else 772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines Func2(Func1()); 782d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif 792d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines return 0; 802d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 81