diff options
author | Dmitry Vyukov <dvyukov@google.com> | 2015-03-02 17:36:02 +0000 |
---|---|---|
committer | Dmitry Vyukov <dvyukov@google.com> | 2015-03-02 17:36:02 +0000 |
commit | 9b281a9fd41a8a09ff6c9c1bf4cc13c1362533c8 (patch) | |
tree | 5964bb033a45d1b6b4738b9ca4f907328a3b5070 /lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc | |
parent | c1b43b1d4c26fabc2199640c9bcc613a8cbc1e6e (diff) | |
download | compiler-rt-9b281a9fd41a8a09ff6c9c1bf4cc13c1362533c8.tar.gz |
asan: fix signal handling during stoptheworld
The problem is that without SA_RESTORER flag, kernel ignores the handler. So tracer actually did not setup any handler.
Add SA_RESTORER flag when setting up handlers.
Add a test that causes SIGSEGV in stoptheworld callback.
Move SignalContext from asan to sanitizer_common to print better diagnostics about signal in the tracer thread.
http://reviews.llvm.org/D8005
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@230978 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc')
-rw-r--r-- | lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc b/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc index cff05ad24..b88e5ce03 100644 --- a/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc +++ b/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc @@ -103,7 +103,7 @@ bool ThreadSuspender::SuspendThread(SuspendedThreadID tid) { VReport(1, "Could not attach to thread %d (errno %d).\n", tid, pterrno); return false; } else { - VReport(1, "Attached to thread %d.\n", tid); + VReport(2, "Attached to thread %d.\n", tid); // The thread is not guaranteed to stop before ptrace returns, so we must // wait on it. Note: if the thread receives a signal concurrently, // we can get notification about the signal before notification about stop. @@ -143,7 +143,7 @@ void ThreadSuspender::ResumeAllThreads() { int pterrno; if (!internal_iserror(internal_ptrace(PTRACE_DETACH, tid, NULL, NULL), &pterrno)) { - VReport(1, "Detached from thread %d.\n", tid); + VReport(2, "Detached from thread %d.\n", tid); } else { // Either the thread is dead, or we are already detached. // The latter case is possible, for instance, if this function was called @@ -202,7 +202,10 @@ struct TracerThreadArgument { static DieCallbackType old_die_callback; // Signal handler to wake up suspended threads when the tracer thread dies. -void TracerThreadSignalHandler(int signum, void *siginfo, void *) { +void TracerThreadSignalHandler(int signum, void *siginfo, void *uctx) { + SignalContext ctx = SignalContext::Create(siginfo, uctx); + VPrintf(1, "Tracer caught signal %d: addr=0x%zx pc=0x%zx sp=0x%zx\n", + signum, ctx.addr, ctx.pc, ctx.sp); if (thread_suspender_instance != NULL) { if (signum == SIGABRT) thread_suspender_instance->KillAllThreads(); |