[PATCH] Share some stack walking code between Windows and Linux

Timur Iskhodzhanov timurrrr at google.com
Fri Nov 8 07:01:10 PST 2013


Hi samsonov,

http://llvm-reviews.chandlerc.com/D2126

Files:
  lib/sanitizer_common/sanitizer_linux_libcdep.cc
  lib/sanitizer_common/sanitizer_stacktrace.cc
  lib/sanitizer_common/sanitizer_stacktrace.h
  lib/sanitizer_common/sanitizer_win.cc

Index: lib/sanitizer_common/sanitizer_linux_libcdep.cc
===================================================================
--- lib/sanitizer_common/sanitizer_linux_libcdep.cc
+++ lib/sanitizer_common/sanitizer_linux_libcdep.cc
@@ -154,24 +154,17 @@
   return UNWIND_CONTINUE;
 }
 
-static bool MatchPc(uptr cur_pc, uptr trace_pc) {
-  return cur_pc - trace_pc <= 64 || trace_pc - cur_pc <= 64;
-}
-
 void StackTrace::SlowUnwindStack(uptr pc, uptr max_depth) {
   size = 0;
   if (max_depth == 0)
     return;
-  UnwindTraceArg arg = {this, Min(max_depth + 1, kStackTraceMax)};
+  UnwindTraceArg arg = {this, Min(max_depth + 2, kStackTraceMax)};
   _Unwind_Backtrace(Unwind_Trace, &arg);
   // We need to pop a few frames so that pc is on top.
+  uptr to_pop = LocatePcInTrace(pc, 64, 6);
   // trace[0] belongs to the current function so we always pop it.
-  int to_pop = 1;
-  /**/ if (size > 1 && MatchPc(pc, trace[1])) to_pop = 1;
-  else if (size > 2 && MatchPc(pc, trace[2])) to_pop = 2;
-  else if (size > 3 && MatchPc(pc, trace[3])) to_pop = 3;
-  else if (size > 4 && MatchPc(pc, trace[4])) to_pop = 4;
-  else if (size > 5 && MatchPc(pc, trace[5])) to_pop = 5;
+  if (to_pop == 0)
+    to_pop = 1;
   PopStackFrames(to_pop);
   trace[0] = pc;
 }
Index: lib/sanitizer_common/sanitizer_stacktrace.cc
===================================================================
--- lib/sanitizer_common/sanitizer_stacktrace.cc
+++ lib/sanitizer_common/sanitizer_stacktrace.cc
@@ -147,4 +147,17 @@
   }
 }
 
+static bool MatchPc(uptr cur_pc, uptr trace_pc, uptr threshold) {
+  return cur_pc - trace_pc <= threshold || trace_pc - cur_pc <= threshold;
+}
+
+uptr
+StackTrace::LocatePcInTrace(uptr pc, uptr pc_threshold, uptr max_pc_depth) {
+  for (uptr i = 0; i < max_pc_depth && i < size; ++i) {
+    if (MatchPc(pc, trace[i], pc_threshold))
+      return i;
+  }
+  return 0;
+}
+
 }  // namespace __sanitizer
Index: lib/sanitizer_common/sanitizer_stacktrace.h
===================================================================
--- lib/sanitizer_common/sanitizer_stacktrace.h
+++ lib/sanitizer_common/sanitizer_stacktrace.h
@@ -67,6 +67,7 @@
                        uptr max_depth);
   void SlowUnwindStack(uptr pc, uptr max_depth);
   void PopStackFrames(uptr count);
+  uptr LocatePcInTrace(uptr pc, uptr pc_threshold = 0, uptr max_pc_depth = -1);
 };
 
 }  // namespace __sanitizer
Index: lib/sanitizer_common/sanitizer_win.cc
===================================================================
--- lib/sanitizer_common/sanitizer_win.cc
+++ lib/sanitizer_common/sanitizer_win.cc
@@ -377,23 +377,13 @@
 }
 
 void StackTrace::SlowUnwindStack(uptr pc, uptr max_depth) {
-  void *tmp[kStackTraceMax];
-
   // FIXME: CaptureStackBackTrace might be too slow for us.
   // FIXME: Compare with StackWalk64.
   // FIXME: Look at LLVMUnhandledExceptionFilter in Signals.inc
-  uptr cs_ret = CaptureStackBackTrace(2, max_depth, tmp, 0);
-  uptr offset = 0;
-  // Skip the RTL frames by searching for the PC in the stacktrace.
-  // FIXME: this doesn't work well for the malloc/free stacks yet.
-  for (uptr i = 0; i < cs_ret; i++) {
-    if (pc != (uptr)tmp[i])
-      continue;
-    offset = i;
-    break;
-  }
-
-  CopyFrom((uptr*)&tmp[offset], cs_ret - offset);
+  size = CaptureStackBackTrace(2, Min(max_depth, kStackTraceMax),
+                               (void**)trace, 0);
+  uptr pc_location = LocatePcInTrace(pc);
+  PopStackFrames(pc_location);
 }
 
 void MaybeOpenReportFile() {
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D2126.1.patch
Type: text/x-patch
Size: 3485 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20131108/8949de37/attachment.bin>


More information about the llvm-commits mailing list