[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