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