[sanitizer] Move GetStackTrace from ASan to sanitizer_common.
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@181424 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/asan/asan_linux.cc b/lib/asan/asan_linux.cc
index 148b5f0..17bb4ca 100644
--- a/lib/asan/asan_linux.cc
+++ b/lib/asan/asan_linux.cc
@@ -102,24 +102,6 @@
// Nothing here for now.
}
-void GetStackTrace(StackTrace *stack, uptr max_s, uptr pc, uptr bp, bool fast) {
-#if defined(__arm__) || \
- defined(__powerpc__) || defined(__powerpc64__) || \
- defined(__sparc__)
- fast = false;
-#endif
- if (!fast)
- return stack->SlowUnwindStack(pc, max_s);
- stack->size = 0;
- stack->trace[0] = pc;
- if (max_s > 1) {
- stack->max_size = max_s;
- if (!asan_inited) return;
- if (AsanThread *t = GetCurrentThread())
- stack->FastUnwindStack(pc, bp, t->stack_top(), t->stack_bottom());
- }
-}
-
#if !SANITIZER_ANDROID
void ReadContextStack(void *context, uptr *stack, uptr *ssize) {
ucontext_t *ucp = (ucontext_t*)context;
diff --git a/lib/asan/asan_mac.cc b/lib/asan/asan_mac.cc
index 63fb5f6..4313534 100644
--- a/lib/asan/asan_mac.cc
+++ b/lib/asan/asan_mac.cc
@@ -229,18 +229,6 @@
void AsanPlatformThreadInit() {
}
-void GetStackTrace(StackTrace *stack, uptr max_s, uptr pc, uptr bp, bool fast) {
- (void)fast;
- stack->size = 0;
- stack->trace[0] = pc;
- if ((max_s) > 1) {
- stack->max_size = max_s;
- if (!asan_inited) return;
- if (AsanThread *t = GetCurrentThread())
- stack->FastUnwindStack(pc, bp, t->stack_top(), t->stack_bottom());
- }
-}
-
void ReadContextStack(void *context, uptr *stack, uptr *ssize) {
UNIMPLEMENTED();
}
diff --git a/lib/asan/asan_stack.h b/lib/asan/asan_stack.h
index cd30abb..176aa18 100644
--- a/lib/asan/asan_stack.h
+++ b/lib/asan/asan_stack.h
@@ -15,12 +15,12 @@
#define ASAN_STACK_H
#include "asan_flags.h"
+#include "asan_thread.h"
#include "sanitizer_common/sanitizer_flags.h"
#include "sanitizer_common/sanitizer_stacktrace.h"
namespace __asan {
-void GetStackTrace(StackTrace *stack, uptr max_s, uptr pc, uptr bp, bool fast);
void PrintStack(StackTrace *stack);
} // namespace __asan
@@ -28,10 +28,24 @@
// Get the stack trace with the given pc and bp.
// The pc will be in the position 0 of the resulting stack trace.
// The bp may refer to the current frame or to the caller's frame.
-// fast_unwind is currently unused.
+#if SANITIZER_WINDOWS
#define GET_STACK_TRACE_WITH_PC_AND_BP(max_s, pc, bp, fast) \
StackTrace stack; \
- GetStackTrace(&stack, max_s, pc, bp, fast)
+ GetStackTrace(&stack, max_s, pc, bp, 0, 0, fast)
+#else
+#define GET_STACK_TRACE_WITH_PC_AND_BP(max_s, pc, bp, fast) \
+ StackTrace stack; \
+ { \
+ uptr stack_top = 0, stack_bottom = 0; \
+ AsanThread *t; \
+ if (asan_inited && (t = GetCurrentThread())) { \
+ stack_top = t->stack_top(); \
+ stack_bottom = t->stack_bottom(); \
+ } \
+ GetStackTrace(&stack, max_s, pc, bp, \
+ stack_top, stack_bottom, fast); \
+ }
+#endif // SANITIZER_WINDOWS
// NOTE: A Rule of thumb is to retrieve stack trace in the interceptors
// as early as possible (in functions exposed to the user), as we generally
diff --git a/lib/asan/asan_win.cc b/lib/asan/asan_win.cc
index 49a3899..f74de72 100644
--- a/lib/asan/asan_win.cc
+++ b/lib/asan/asan_win.cc
@@ -32,30 +32,6 @@
static bool dbghelp_initialized = false;
#pragma comment(lib, "dbghelp.lib")
-void GetStackTrace(StackTrace *stack, uptr max_s, uptr pc, uptr bp, bool fast) {
- (void)fast;
- stack->max_size = max_s;
- 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(1, stack->max_size, 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;
- }
-
- stack->size = cs_ret - offset;
- for (uptr i = 0; i < stack->size; i++)
- stack->trace[i] = (uptr)tmp[i + offset];
-}
-
// ---------------------- TSD ---------------- {{{1
static bool tsd_key_inited = false;
diff --git a/lib/sanitizer_common/sanitizer_posix.cc b/lib/sanitizer_common/sanitizer_posix.cc
index 2aae414..7fec5cf 100644
--- a/lib/sanitizer_common/sanitizer_posix.cc
+++ b/lib/sanitizer_common/sanitizer_posix.cc
@@ -18,6 +18,7 @@
#include "sanitizer_common.h"
#include "sanitizer_libc.h"
#include "sanitizer_procmaps.h"
+#include "sanitizer_stacktrace.h"
#include <errno.h>
#include <pthread.h>
@@ -228,6 +229,26 @@
return isatty(fd);
}
+void GetStackTrace(StackTrace *stack, uptr max_s, uptr pc, uptr bp,
+ uptr stack_top, uptr stack_bottom, bool fast) {
+#if !SANITIZER_CAN_FAST_UNWIND
+ fast = false;
+#endif
+#if SANITIZER_MAC
+ // Always unwind fast on Mac.
+ (void)fast;
+#else
+ if (!fast || (stack_top == stack_bottom))
+ return stack->SlowUnwindStack(pc, max_s);
+#endif // SANITIZER_MAC
+ stack->size = 0;
+ stack->trace[0] = pc;
+ if (max_s > 1) {
+ stack->max_size = max_s;
+ stack->FastUnwindStack(pc, bp, stack_top, stack_bottom);
+ }
+}
+
} // namespace __sanitizer
-#endif // SANITIZER_LINUX || __APPLE_
+#endif // SANITIZER_LINUX || SANITIZER_MAC
diff --git a/lib/sanitizer_common/sanitizer_stacktrace.h b/lib/sanitizer_common/sanitizer_stacktrace.h
index b9ea9b4..fcfdd7e 100644
--- a/lib/sanitizer_common/sanitizer_stacktrace.h
+++ b/lib/sanitizer_common/sanitizer_stacktrace.h
@@ -19,6 +19,14 @@
static const uptr kStackTraceMax = 256;
+#if SANITIZER_LINUX && (defined(__arm__) || \
+ defined(__powerpc__) || defined(__powerpc64__) || \
+ defined(__sparc__))
+#define SANITIZER_CAN_FAST_UNWIND 0
+#else
+#define SANITIZER_CAN_FAST_UNWIND 1
+#endif
+
struct StackTrace {
typedef bool (*SymbolizeCallback)(const void *pc, char *out_buffer,
int out_size);
@@ -61,6 +69,9 @@
const char *StripPathPrefix(const char *filepath,
const char *strip_file_prefix);
+void GetStackTrace(StackTrace *stack, uptr max_s, uptr pc, uptr bp,
+ uptr stack_top, uptr stack_bottom, bool fast);
+
} // namespace __sanitizer
// Use this macro if you want to print stack trace with the caller
diff --git a/lib/sanitizer_common/sanitizer_win.cc b/lib/sanitizer_common/sanitizer_win.cc
index 48874a1..95445be 100644
--- a/lib/sanitizer_common/sanitizer_win.cc
+++ b/lib/sanitizer_common/sanitizer_win.cc
@@ -23,8 +23,9 @@
#include "sanitizer_common.h"
#include "sanitizer_libc.h"
-#include "sanitizer_placement_new.h"
#include "sanitizer_mutex.h"
+#include "sanitizer_placement_new.h"
+#include "sanitizer_stacktrace.h"
namespace __sanitizer {
@@ -346,6 +347,33 @@
*tls_size = 0;
}
+void GetStackTrace(StackTrace *stack, uptr max_s, uptr pc, uptr bp,
+ uptr stack_top, uptr stack_bottom, bool fast) {
+ (void)fast;
+ (void)stack_top;
+ (void)stack_bottom;
+ stack->max_size = max_s;
+ 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(1, stack->max_size, 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;
+ }
+
+ stack->size = cs_ret - offset;
+ for (uptr i = 0; i < stack->size; i++)
+ stack->trace[i] = (uptr)tmp[i + offset];
+}
+
} // namespace __sanitizer
#endif // _WIN32