16efa4d6cf9bb214a5e8ddbb224a69b38c4ae6de6Alexey Samsonov// RUN: %clangxx_asan -O2 %s -o %t 2f2366a95ae2b54569bf556c11580a14481f8700fAlexey Samsonov// RUN: ASAN_OPTIONS=fast_unwind_on_malloc=1 not %t 2>&1 | FileCheck %s --check-prefix=CHECK-FAST 3f2366a95ae2b54569bf556c11580a14481f8700fAlexey Samsonov// RUN: ASAN_OPTIONS=fast_unwind_on_malloc=0 not %t 2>&1 | FileCheck %s --check-prefix=CHECK-SLOW 4308dd557f002c747500fdd2603a35c9675461491Kostya Serebryany 5308dd557f002c747500fdd2603a35c9675461491Kostya Serebryany// Test how well we unwind in presence of qsort in the stack 6308dd557f002c747500fdd2603a35c9675461491Kostya Serebryany// (i.e. if we can unwind through a function compiled w/o frame pointers). 7308dd557f002c747500fdd2603a35c9675461491Kostya Serebryany// https://code.google.com/p/address-sanitizer/issues/detail?id=137 8098847d2a24ca010e543adb3e1140d56f30a6a90Alexey Samsonov 9098847d2a24ca010e543adb3e1140d56f30a6a90Alexey Samsonov// Fast unwinder is only avaliable on x86_64 and i386. 10a6e7d8d6369eb676d8c4ed4223e42743e367057fAlexey Samsonov// REQUIRES: x86_64-supported-target 11098847d2a24ca010e543adb3e1140d56f30a6a90Alexey Samsonov 12308dd557f002c747500fdd2603a35c9675461491Kostya Serebryany#include <stdlib.h> 13308dd557f002c747500fdd2603a35c9675461491Kostya Serebryany#include <stdio.h> 14308dd557f002c747500fdd2603a35c9675461491Kostya Serebryany 1506abe7fa574012ada5c0474f60eb6398e0c1a808Kostya Serebryanyint *GlobalPtr; 16308dd557f002c747500fdd2603a35c9675461491Kostya Serebryany 1706abe7fa574012ada5c0474f60eb6398e0c1a808Kostya Serebryanyextern "C" { 18308dd557f002c747500fdd2603a35c9675461491Kostya Serebryanyint QsortCallback(const void *a, const void *b) { 19308dd557f002c747500fdd2603a35c9675461491Kostya Serebryany char *x = (char*)a; 20308dd557f002c747500fdd2603a35c9675461491Kostya Serebryany char *y = (char*)b; 21308dd557f002c747500fdd2603a35c9675461491Kostya Serebryany printf("Calling QsortCallback\n"); 2206abe7fa574012ada5c0474f60eb6398e0c1a808Kostya Serebryany GlobalPtr = new int[10]; 23308dd557f002c747500fdd2603a35c9675461491Kostya Serebryany return (int)*x - (int)*y; 24308dd557f002c747500fdd2603a35c9675461491Kostya Serebryany} 25308dd557f002c747500fdd2603a35c9675461491Kostya Serebryany 26308dd557f002c747500fdd2603a35c9675461491Kostya Serebryany__attribute__((noinline)) 27308dd557f002c747500fdd2603a35c9675461491Kostya Serebryanyvoid MyQsort(char *a, size_t size) { 28308dd557f002c747500fdd2603a35c9675461491Kostya Serebryany printf("Calling qsort\n"); 29308dd557f002c747500fdd2603a35c9675461491Kostya Serebryany qsort(a, size, sizeof(char), QsortCallback); 30308dd557f002c747500fdd2603a35c9675461491Kostya Serebryany printf("Done\n"); // Avoid tail call. 31308dd557f002c747500fdd2603a35c9675461491Kostya Serebryany} 3206abe7fa574012ada5c0474f60eb6398e0c1a808Kostya Serebryany} // extern "C" 33308dd557f002c747500fdd2603a35c9675461491Kostya Serebryany 34308dd557f002c747500fdd2603a35c9675461491Kostya Serebryanyint main() { 35308dd557f002c747500fdd2603a35c9675461491Kostya Serebryany char a[2] = {1, 2}; 36308dd557f002c747500fdd2603a35c9675461491Kostya Serebryany MyQsort(a, 2); 3706abe7fa574012ada5c0474f60eb6398e0c1a808Kostya Serebryany return GlobalPtr[10]; 38308dd557f002c747500fdd2603a35c9675461491Kostya Serebryany} 39308dd557f002c747500fdd2603a35c9675461491Kostya Serebryany 4006abe7fa574012ada5c0474f60eb6398e0c1a808Kostya Serebryany// Fast unwind: can not unwind through qsort. 4106abe7fa574012ada5c0474f60eb6398e0c1a808Kostya Serebryany// FIXME: this test does not properly work with slow unwind yet. 4206abe7fa574012ada5c0474f60eb6398e0c1a808Kostya Serebryany 4306abe7fa574012ada5c0474f60eb6398e0c1a808Kostya Serebryany// CHECK-FAST: ERROR: AddressSanitizer: heap-buffer-overflow 4449d616ec42ab420ce3ebcbe846b21e3729adf5acKostya Serebryany// CHECK-FAST: is located 0 bytes to the right 4549d616ec42ab420ce3ebcbe846b21e3729adf5acKostya Serebryany// CHECK-FAST: #0{{.*}}operator new 4649d616ec42ab420ce3ebcbe846b21e3729adf5acKostya Serebryany// CHECK-FAST-NEXT: #1{{.*}}QsortCallback 4749d616ec42ab420ce3ebcbe846b21e3729adf5acKostya Serebryany// CHECK-FAST-NOT: MyQsort 4849d616ec42ab420ce3ebcbe846b21e3729adf5acKostya Serebryany// 4906abe7fa574012ada5c0474f60eb6398e0c1a808Kostya Serebryany// CHECK-SLOW: ERROR: AddressSanitizer: heap-buffer-overflow 5049d616ec42ab420ce3ebcbe846b21e3729adf5acKostya Serebryany// CHECK-SLOW: is located 0 bytes to the right 5149d616ec42ab420ce3ebcbe846b21e3729adf5acKostya Serebryany// CHECK-SLOW: #0{{.*}}operator new 5249d616ec42ab420ce3ebcbe846b21e3729adf5acKostya Serebryany// CHECK-SLOW-NEXT: #1{{.*}}QsortCallback 5349d616ec42ab420ce3ebcbe846b21e3729adf5acKostya Serebryany// CHECK-SLOW: #{{.*}}MyQsort 5449d616ec42ab420ce3ebcbe846b21e3729adf5acKostya Serebryany// CHECK-SLOW-NEXT: #{{.*}}main 55