1673dc3d4SNico Weber // RUN: %clangxx_asan -O2 %s -o %t 2673dc3d4SNico Weber // RUN: %env_asan_opts=fast_unwind_on_malloc=1 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-FAST 3673dc3d4SNico Weber // RUN: %env_asan_opts=fast_unwind_on_malloc=0 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-SLOW 4673dc3d4SNico Weber 5673dc3d4SNico Weber // Test how well we unwind in presence of qsort in the stack 6673dc3d4SNico Weber // (i.e. if we can unwind through a function compiled w/o frame pointers). 7673dc3d4SNico Weber // https://code.google.com/p/address-sanitizer/issues/detail?id=137 8673dc3d4SNico Weber 9673dc3d4SNico Weber // Fast unwinder is only available on x86_64 and i386. 10673dc3d4SNico Weber // REQUIRES: x86-target-arch 11673dc3d4SNico Weber 12673dc3d4SNico Weber // REQUIRES: compiler-rt-optimized 13673dc3d4SNico Weber 14673dc3d4SNico Weber #include <stdlib.h> 15673dc3d4SNico Weber #include <stdio.h> 16673dc3d4SNico Weber 17673dc3d4SNico Weber int *GlobalPtr; 18673dc3d4SNico Weber 19673dc3d4SNico Weber extern "C" { QsortCallback(const void * a,const void * b)20673dc3d4SNico Weberint QsortCallback(const void *a, const void *b) { 21673dc3d4SNico Weber char *x = (char*)a; 22673dc3d4SNico Weber char *y = (char*)b; 23673dc3d4SNico Weber printf("Calling QsortCallback\n"); 24673dc3d4SNico Weber GlobalPtr = new int[10]; 25673dc3d4SNico Weber return (int)*x - (int)*y; 26673dc3d4SNico Weber } 27673dc3d4SNico Weber 28673dc3d4SNico Weber __attribute__((noinline)) MyQsort(char * a,size_t size)29673dc3d4SNico Webervoid MyQsort(char *a, size_t size) { 30673dc3d4SNico Weber printf("Calling qsort\n"); 31673dc3d4SNico Weber qsort(a, size, sizeof(char), QsortCallback); 32673dc3d4SNico Weber printf("Done\n"); // Avoid tail call. 33673dc3d4SNico Weber } 34673dc3d4SNico Weber } // extern "C" 35673dc3d4SNico Weber main()36673dc3d4SNico Weberint main() { 37673dc3d4SNico Weber char a[2] = {1, 2}; 38673dc3d4SNico Weber MyQsort(a, 2); 39673dc3d4SNico Weber return GlobalPtr[10]; 40673dc3d4SNico Weber } 41673dc3d4SNico Weber 42673dc3d4SNico Weber // Fast unwind may not unwind through qsort. 43673dc3d4SNico Weber // CHECK-FAST: ERROR: AddressSanitizer: heap-buffer-overflow 44*be366041SFlorian Mayer // CHECK-FAST: is located 0 bytes after 45673dc3d4SNico Weber // CHECK-FAST: #0{{.*}}operator new 46673dc3d4SNico Weber // CHECK-FAST-NEXT: #1{{.*}}QsortCallback 47673dc3d4SNico Weber 48673dc3d4SNico Weber // CHECK-SLOW: ERROR: AddressSanitizer: heap-buffer-overflow 49*be366041SFlorian Mayer // CHECK-SLOW: is located 0 bytes after 50673dc3d4SNico Weber // CHECK-SLOW: #0{{.*}}operator new 51673dc3d4SNico Weber // CHECK-SLOW-NEXT: #1{{.*}}QsortCallback 52673dc3d4SNico Weber // CHECK-SLOW: #{{.*}}MyQsort 53673dc3d4SNico Weber // CHECK-SLOW-NEXT: #{{.*}}main 54