[asan] pop the internal stack frames in SlowUnwindStack, extend the test to check...
authorKostya Serebryany <kcc@google.com>
Thu, 13 Dec 2012 12:31:55 +0000 (12:31 +0000)
committerKostya Serebryany <kcc@google.com>
Thu, 13 Dec 2012 12:31:55 +0000 (12:31 +0000)
llvm-svn: 170124

compiler-rt/lib/asan/asan_linux.cc
compiler-rt/lib/asan/lit_tests/Linux/malloc-in-qsort.cc
compiler-rt/lib/sanitizer_common/sanitizer_linux.cc
compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.h

index 02a3d14..ff91e89 100644 (file)
@@ -129,7 +129,7 @@ void GetStackTrace(StackTrace *stack, uptr max_s, uptr pc, uptr bp, bool fast) {
   fast = false;
 #endif
   if (!fast)
-    return stack->SlowUnwindStack(pc, max_s, 3);
+    return stack->SlowUnwindStack(pc, max_s);
   stack->size = 0;
   stack->trace[0] = pc;
   if (max_s > 1) {
index 5140890..a3fa255 100644 (file)
@@ -37,4 +37,14 @@ int main() {
 // FIXME: this test does not properly work with slow unwind yet.
 
 // CHECK-FAST: ERROR: AddressSanitizer: heap-buffer-overflow
+// CHECK-FAST: is located 0 bytes to the right
+// CHECK-FAST: #0{{.*}}operator new
+// CHECK-FAST-NEXT: #1{{.*}}QsortCallback
+// CHECK-FAST-NOT: MyQsort
+//
 // CHECK-SLOW: ERROR: AddressSanitizer: heap-buffer-overflow
+// CHECK-SLOW: is located 0 bytes to the right
+// CHECK-SLOW: #0{{.*}}operator new
+// CHECK-SLOW-NEXT: #1{{.*}}QsortCallback
+// CHECK-SLOW: #{{.*}}MyQsort
+// CHECK-SLOW-NEXT: #{{.*}}main
index 6a0f261..a0f0274 100644 (file)
@@ -411,14 +411,24 @@ _Unwind_Reason_Code Unwind_Trace(struct _Unwind_Context *ctx, void *param) {
   return UNWIND_CONTINUE;
 }
 
-void StackTrace::SlowUnwindStack(uptr pc, uptr max_depth, uptr frames_to_pop) {
+static bool MatchPc(uptr cur_pc, uptr trace_pc) {
+  return cur_pc - trace_pc <= 8;
+}
+
+void StackTrace::SlowUnwindStack(uptr pc, uptr max_depth) {
   this->size = 0;
-  this->trace[0] = pc;
   this->max_size = max_depth;
   if (max_depth > 1) {
     _Unwind_Backtrace(Unwind_Trace, this);
-    this->PopStackFrames(frames_to_pop);
+    // We need to pop a few (up to 3) frames so that pc is on top.
+    // trace[0] belongs to the current function.
+    int to_pop = 1;
+    /**/ if (size >= 2 && MatchPc(pc, trace[1])) to_pop = 2;
+    else if (size >= 3 && MatchPc(pc, trace[2])) to_pop = 3;
+    else if (size >= 4 && MatchPc(pc, trace[3])) to_pop = 4;
+    this->PopStackFrames(to_pop);
   }
+  this->trace[0] = pc;
 }
 
 }  // namespace __sanitizer
index 64979ec..90ad31f 100644 (file)
@@ -44,7 +44,7 @@ struct StackTrace {
   }
 
   void FastUnwindStack(uptr pc, uptr bp, uptr stack_top, uptr stack_bottom);
-  void SlowUnwindStack(uptr pc, uptr max_depth, uptr frames_to_pop);
+  void SlowUnwindStack(uptr pc, uptr max_depth);
 
   void PopStackFrames(uptr count);