[sanitizer] Move GetStackTrace from ASan to sanitizer_common.

llvm-svn: 181424
This commit is contained in:
Sergey Matveev 2013-05-08 12:45:55 +00:00
parent 08e53ee551
commit af179b8d63
7 changed files with 79 additions and 59 deletions

View File

@ -102,24 +102,6 @@ void AsanPlatformThreadInit() {
// 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;

View File

@ -229,18 +229,6 @@ bool AsanInterceptsSignal(int signum) {
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();
}

View File

@ -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 @@ void PrintStack(StackTrace *stack);
// 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

View File

@ -32,30 +32,6 @@ static BlockingMutex dbghelp_lock(LINKER_INITIALIZED);
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;

View File

@ -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 @@ int internal_isatty(fd_t fd) {
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

View File

@ -19,6 +19,14 @@ namespace __sanitizer {
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 @@ struct StackTrace {
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

View File

@ -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 @@ void GetThreadStackAndTls(bool main, uptr *stk_addr, uptr *stk_size,
*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