forked from OSchip/llvm-project
[sanitizer] Move GetStackTrace from ASan to sanitizer_common.
llvm-svn: 181424
This commit is contained in:
parent
08e53ee551
commit
af179b8d63
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue