forked from OSchip/llvm-project
[Sanitizers] Enable stack traces on FreeBSD
Differential Revision: http://reviews.llvm.org/D6086 llvm-svn: 221595
This commit is contained in:
parent
156ffbc4c0
commit
dc6cbfe859
|
@ -33,6 +33,7 @@
|
|||
namespace __asan {
|
||||
|
||||
void AsanOnSIGSEGV(int, void *siginfo, void *context) {
|
||||
ScopedDeadlySignal signal_scope(GetCurrentThread());
|
||||
uptr addr = (uptr)((siginfo_t*)siginfo)->si_addr;
|
||||
int code = (int)((siginfo_t*)siginfo)->si_code;
|
||||
// Write the first message using the bullet-proof write.
|
||||
|
|
|
@ -35,6 +35,10 @@ void GetStackTraceWithPcBpAndContext(BufferedStackTrace *stack, uptr max_depth,
|
|||
stack->size = 0;
|
||||
if (LIKELY(asan_inited)) {
|
||||
if ((t = GetCurrentThread()) && !t->isUnwinding()) {
|
||||
// On FreeBSD the slow unwinding that leverages _Unwind_Backtrace()
|
||||
// yields the call stack of the signal's handler and not of the code
|
||||
// that raised the signal (as it does on Linux).
|
||||
if (SANITIZER_FREEBSD && t->isInDeadlySignal()) fast = true;
|
||||
uptr stack_top = t->stack_top();
|
||||
uptr stack_bottom = t->stack_bottom();
|
||||
ScopedUnwinding unwind_scope(t);
|
||||
|
|
|
@ -108,6 +108,10 @@ class AsanThread {
|
|||
bool isUnwinding() const { return unwinding_; }
|
||||
void setUnwinding(bool b) { unwinding_ = b; }
|
||||
|
||||
// True if we are in a deadly signal handler.
|
||||
bool isInDeadlySignal() const { return in_deadly_signal_; }
|
||||
void setInDeadlySignal(bool b) { in_deadly_signal_ = b; }
|
||||
|
||||
AsanThreadLocalMallocStorage &malloc_storage() { return malloc_storage_; }
|
||||
AsanStats &stats() { return stats_; }
|
||||
|
||||
|
@ -133,6 +137,7 @@ class AsanThread {
|
|||
AsanThreadLocalMallocStorage malloc_storage_;
|
||||
AsanStats stats_;
|
||||
bool unwinding_;
|
||||
bool in_deadly_signal_;
|
||||
};
|
||||
|
||||
// ScopedUnwinding is a scope for stacktracing member of a context
|
||||
|
@ -147,6 +152,20 @@ class ScopedUnwinding {
|
|||
AsanThread *thread;
|
||||
};
|
||||
|
||||
// ScopedDeadlySignal is a scope for handling deadly signals.
|
||||
class ScopedDeadlySignal {
|
||||
public:
|
||||
explicit ScopedDeadlySignal(AsanThread *t) : thread(t) {
|
||||
if (thread) thread->setInDeadlySignal(true);
|
||||
}
|
||||
~ScopedDeadlySignal() {
|
||||
if (thread) thread->setInDeadlySignal(false);
|
||||
}
|
||||
|
||||
private:
|
||||
AsanThread *thread;
|
||||
};
|
||||
|
||||
struct CreateThreadContextArgs {
|
||||
AsanThread *thread;
|
||||
StackTrace *stack;
|
||||
|
|
|
@ -29,6 +29,15 @@ static const uptr kStackTraceMax = 256;
|
|||
# define SANITIZER_CAN_FAST_UNWIND 1
|
||||
#endif
|
||||
|
||||
// Fast unwind is the only option on Mac for now; we will need to
|
||||
// revisit this macro when slow unwind works on Mac, see
|
||||
// https://code.google.com/p/address-sanitizer/issues/detail?id=137
|
||||
#if SANITIZER_MAC
|
||||
# define SANITIZER_CAN_SLOW_UNWIND 0
|
||||
#else
|
||||
# define SANITIZER_CAN_SLOW_UNWIND 1
|
||||
#endif
|
||||
|
||||
struct StackTrace {
|
||||
const uptr *trace;
|
||||
uptr size;
|
||||
|
@ -40,13 +49,9 @@ struct StackTrace {
|
|||
void Print() const;
|
||||
|
||||
static bool WillUseFastUnwind(bool request_fast_unwind) {
|
||||
// Check if fast unwind is available. Fast unwind is the only option on Mac.
|
||||
// It is also the only option on FreeBSD as the slow unwinding that
|
||||
// leverages _Unwind_Backtrace() yields the call stack of the signal's
|
||||
// handler and not of the code that raised the signal (as it does on Linux).
|
||||
if (!SANITIZER_CAN_FAST_UNWIND)
|
||||
return false;
|
||||
else if (SANITIZER_MAC != 0 || SANITIZER_FREEBSD != 0)
|
||||
else if (!SANITIZER_CAN_SLOW_UNWIND)
|
||||
return true;
|
||||
return request_fast_unwind;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue