[compiler-rt] r221595 - [Sanitizers] Enable stack traces on FreeBSD
Viktor Kutuzov
vkutuzov at accesssoftek.com
Mon Nov 10 07:22:04 PST 2014
Author: vkutuzov
Date: Mon Nov 10 09:22:04 2014
New Revision: 221595
URL: http://llvm.org/viewvc/llvm-project?rev=221595&view=rev
Log:
[Sanitizers] Enable stack traces on FreeBSD
Differential Revision: http://reviews.llvm.org/D6086
Modified:
compiler-rt/trunk/lib/asan/asan_posix.cc
compiler-rt/trunk/lib/asan/asan_stack.h
compiler-rt/trunk/lib/asan/asan_thread.h
compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace.h
Modified: compiler-rt/trunk/lib/asan/asan_posix.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_posix.cc?rev=221595&r1=221594&r2=221595&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_posix.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_posix.cc Mon Nov 10 09:22:04 2014
@@ -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.
Modified: compiler-rt/trunk/lib/asan/asan_stack.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_stack.h?rev=221595&r1=221594&r2=221595&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_stack.h (original)
+++ compiler-rt/trunk/lib/asan/asan_stack.h Mon Nov 10 09:22:04 2014
@@ -35,6 +35,10 @@ void GetStackTraceWithPcBpAndContext(Buf
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);
Modified: compiler-rt/trunk/lib/asan/asan_thread.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_thread.h?rev=221595&r1=221594&r2=221595&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_thread.h (original)
+++ compiler-rt/trunk/lib/asan/asan_thread.h Mon Nov 10 09:22:04 2014
@@ -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
@@ -145,6 +150,20 @@ class ScopedUnwinding {
private:
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 {
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace.h?rev=221595&r1=221594&r2=221595&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace.h Mon Nov 10 09:22:04 2014
@@ -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;
}
More information about the llvm-commits
mailing list