summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Potapenko <glider@google.com>2014-01-31 13:10:07 +0000
committerAlexander Potapenko <glider@google.com>2014-01-31 13:10:07 +0000
commit4c26afdb206b13ae5cdc5e2a074a6cadc0d969a5 (patch)
treeec3f7f602ad4f68a2bef7b9765cf07d507f536fe
parent7c8ecc28166e5f23cc8479ebcf69effe9a006dad (diff)
[ASan] Move the SIGSEGV/SIGBUS handling to sanitizer_common
This change is a part of refactoring intended to have common signal handling behavior in all tools. This particular CL moves InstallSignalHandlers() into sanitizer_common (making it InstallDeadlySignalHandlers()), but doesn't enable default signal handlers for any tool other than ASan. git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@200542 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/asan/asan_interceptors.cc7
-rw-r--r--lib/asan/asan_internal.h2
-rw-r--r--lib/asan/asan_posix.cc26
-rw-r--r--lib/asan/asan_rtl.cc2
-rw-r--r--lib/asan/asan_win.cc4
-rw-r--r--lib/sanitizer_common/sanitizer_common.h4
-rw-r--r--lib/sanitizer_common/sanitizer_libc.h2
-rw-r--r--lib/sanitizer_common/sanitizer_linux.cc5
-rw-r--r--lib/sanitizer_common/sanitizer_linux_libcdep.cc11
-rw-r--r--lib/sanitizer_common/sanitizer_mac.cc11
-rw-r--r--lib/sanitizer_common/sanitizer_posix_libcdep.cc25
-rw-r--r--lib/sanitizer_common/sanitizer_win.cc9
12 files changed, 77 insertions, 31 deletions
diff --git a/lib/asan/asan_interceptors.cc b/lib/asan/asan_interceptors.cc
index c63de35c3..f5efbd3f6 100644
--- a/lib/asan/asan_interceptors.cc
+++ b/lib/asan/asan_interceptors.cc
@@ -202,6 +202,13 @@ INTERCEPTOR(int, sigaction, int signum, const struct sigaction *act,
}
return 0;
}
+
+extern "C"
+int __sanitizer_sigaction_f(int signum, const void *act, void *oldact) {
+ return REAL(sigaction)(signum,
+ (struct sigaction *)act, (struct sigaction *)oldact);
+}
+
#elif SANITIZER_POSIX
// We need to have defined REAL(sigaction) on posix systems.
DEFINE_REAL(int, sigaction, int signum, const struct sigaction *act,
diff --git a/lib/asan/asan_internal.h b/lib/asan/asan_internal.h
index f0c9a49a6..3914fbbd1 100644
--- a/lib/asan/asan_internal.h
+++ b/lib/asan/asan_internal.h
@@ -71,10 +71,10 @@ void ReplaceSystemMalloc();
void *AsanDoesNotSupportStaticLinkage();
void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp);
+void AsanOnSIGSEGV(int, void *siginfo, void *context);
void MaybeReexec();
bool AsanInterceptsSignal(int signum);
-void InstallSignalHandlers();
void ReadContextStack(void *context, uptr *stack, uptr *ssize);
void AsanPlatformThreadInit();
void StopInitOrderChecking();
diff --git a/lib/asan/asan_posix.cc b/lib/asan/asan_posix.cc
index 9a306309a..d4bf84f8e 100644
--- a/lib/asan/asan_posix.cc
+++ b/lib/asan/asan_posix.cc
@@ -32,21 +32,8 @@
namespace __asan {
-static void MaybeInstallSigaction(int signum,
- void (*handler)(int, siginfo_t *, void *)) {
- if (!AsanInterceptsSignal(signum))
- return;
- struct sigaction sigact;
- REAL(memset)(&sigact, 0, sizeof(sigact));
- sigact.sa_sigaction = handler;
- sigact.sa_flags = SA_SIGINFO;
- if (common_flags()->use_sigaltstack) sigact.sa_flags |= SA_ONSTACK;
- CHECK_EQ(0, REAL(sigaction)(signum, &sigact, 0));
- VReport(1, "Installed the sigaction for signal %d\n", signum);
-}
-
-static void ASAN_OnSIGSEGV(int, siginfo_t *siginfo, void *context) {
- uptr addr = (uptr)siginfo->si_addr;
+void AsanOnSIGSEGV(int, void *siginfo, void *context) {
+ uptr addr = (uptr)((siginfo_t*)siginfo)->si_addr;
// Write the first message using the bullet-proof write.
if (13 != internal_write(2, "ASAN:SIGSEGV\n", 13)) Die();
uptr pc, sp, bp;
@@ -54,15 +41,6 @@ static void ASAN_OnSIGSEGV(int, siginfo_t *siginfo, void *context) {
ReportSIGSEGV(pc, sp, bp, addr);
}
-void InstallSignalHandlers() {
- // Set the alternate signal stack for the main thread.
- // This will cause SetAlternateSignalStack to be called twice, but the stack
- // will be actually set only once.
- if (common_flags()->use_sigaltstack) SetAlternateSignalStack();
- MaybeInstallSigaction(SIGSEGV, ASAN_OnSIGSEGV);
- MaybeInstallSigaction(SIGBUS, ASAN_OnSIGSEGV);
-}
-
// ---------------------- TSD ---------------- {{{1
static pthread_key_t tsd_key;
diff --git a/lib/asan/asan_rtl.cc b/lib/asan/asan_rtl.cc
index 3d8ed9f84..2a97ed595 100644
--- a/lib/asan/asan_rtl.cc
+++ b/lib/asan/asan_rtl.cc
@@ -486,7 +486,7 @@ static void AsanInitInternal() {
}
AsanTSDInit(PlatformTSDDtor);
- InstallSignalHandlers();
+ InstallDeadlySignalHandlers(AsanOnSIGSEGV);
// Allocator should be initialized before starting external symbolizer, as
// fork() on Mac locks the allocator.
diff --git a/lib/asan/asan_win.cc b/lib/asan/asan_win.cc
index f06e74030..80d70b9c0 100644
--- a/lib/asan/asan_win.cc
+++ b/lib/asan/asan_win.cc
@@ -70,10 +70,6 @@ void *AsanDoesNotSupportStaticLinkage() {
return 0;
}
-void InstallSignalHandlers() {
- // FIXME: Decide what to do on Windows.
-}
-
void AsanPlatformThreadInit() {
// Nothing here for now.
}
diff --git a/lib/sanitizer_common/sanitizer_common.h b/lib/sanitizer_common/sanitizer_common.h
index 1398f75a6..a5c8df0c3 100644
--- a/lib/sanitizer_common/sanitizer_common.h
+++ b/lib/sanitizer_common/sanitizer_common.h
@@ -214,6 +214,10 @@ typedef void (*CheckFailedCallbackType)(const char *, int, const char *,
void SetCheckFailedCallback(CheckFailedCallbackType callback);
// Functions related to signal handling.
+typedef void (*SignalHandlerType)(int, void *, void *);
+bool IsDeadlySignal(int signum);
+void InstallDeadlySignalHandlers(SignalHandlerType handler);
+// Alternative signal stack (POSIX-only).
void SetAlternateSignalStack();
void UnsetAlternateSignalStack();
diff --git a/lib/sanitizer_common/sanitizer_libc.h b/lib/sanitizer_common/sanitizer_libc.h
index 9a1b4b539..0768ae16e 100644
--- a/lib/sanitizer_common/sanitizer_libc.h
+++ b/lib/sanitizer_common/sanitizer_libc.h
@@ -97,6 +97,8 @@ uptr internal_sched_yield();
// Error handling
bool internal_iserror(uptr retval, int *rverrno = 0);
+int internal_sigaction(int signum, const void *act, void *oldact);
+
} // namespace __sanitizer
#endif // SANITIZER_LIBC_H
diff --git a/lib/sanitizer_common/sanitizer_linux.cc b/lib/sanitizer_common/sanitizer_linux.cc
index 03d3dc5d6..2a954772b 100644
--- a/lib/sanitizer_common/sanitizer_linux.cc
+++ b/lib/sanitizer_common/sanitizer_linux.cc
@@ -16,6 +16,7 @@
#if SANITIZER_LINUX
#include "sanitizer_common.h"
+#include "sanitizer_flags.h"
#include "sanitizer_internal_defs.h"
#include "sanitizer_libc.h"
#include "sanitizer_linux.h"
@@ -698,6 +699,10 @@ void AndroidLogWrite(const char *buffer) {
}
#endif
+bool IsDeadlySignal(int signum) {
+ return (signum == SIGSEGV) && common_flags()->handle_segv;
+}
+
} // namespace __sanitizer
#endif // SANITIZER_LINUX
diff --git a/lib/sanitizer_common/sanitizer_linux_libcdep.cc b/lib/sanitizer_common/sanitizer_linux_libcdep.cc
index 0b951bd3e..d64a89293 100644
--- a/lib/sanitizer_common/sanitizer_linux_libcdep.cc
+++ b/lib/sanitizer_common/sanitizer_linux_libcdep.cc
@@ -24,6 +24,7 @@
#include <dlfcn.h>
#include <pthread.h>
+#include <signal.h>
#include <sys/prctl.h>
#include <sys/resource.h>
#include <unwind.h>
@@ -39,7 +40,6 @@ extern "C" SANITIZER_WEAK_ATTRIBUTE int
__sanitizer_pthread_attr_getstack(void *attr, void **addr, size_t *size);
static int my_pthread_attr_getstack(void *attr, void **addr, size_t *size) {
-#
if (__sanitizer_pthread_attr_getstack)
return __sanitizer_pthread_attr_getstack((pthread_attr_t *)attr, addr,
size);
@@ -50,6 +50,15 @@ static int my_pthread_attr_getstack(void *attr, void **addr, size_t *size) {
namespace __sanitizer {
+extern "C" SANITIZER_WEAK_ATTRIBUTE int
+__sanitizer_sigaction_f(int signum, const void *act, void *oldact);
+
+int internal_sigaction(int signum, const void *act, void *oldact) {
+ if (__sanitizer_sigaction_f)
+ return __sanitizer_sigaction_f(signum, act, oldact);
+ return sigaction(signum, (struct sigaction *)act, (struct sigaction *)oldact);
+}
+
#ifndef SANITIZER_GO
void GetThreadStackTopAndBottom(bool at_initialization, uptr *stack_top,
uptr *stack_bottom) {
diff --git a/lib/sanitizer_common/sanitizer_mac.cc b/lib/sanitizer_common/sanitizer_mac.cc
index 3cc3a6b5b..e6c95bb69 100644
--- a/lib/sanitizer_common/sanitizer_mac.cc
+++ b/lib/sanitizer_common/sanitizer_mac.cc
@@ -23,6 +23,7 @@
#include <stdio.h>
#include "sanitizer_common.h"
+#include "sanitizer_flags.h"
#include "sanitizer_internal_defs.h"
#include "sanitizer_libc.h"
#include "sanitizer_placement_new.h"
@@ -32,6 +33,7 @@
#include <fcntl.h>
#include <pthread.h>
#include <sched.h>
+#include <signal.h>
#include <sys/mman.h>
#include <sys/resource.h>
#include <sys/stat.h>
@@ -118,6 +120,11 @@ uptr internal_getpid() {
return getpid();
}
+int internal_sigaction(int signum, const void *act, void *oldact) {
+ return sigaction(signum,
+ (struct sigaction *)act, (struct sigaction *)oldact);
+}
+
// ----------------- sanitizer_common.h
bool FileExists(const char *filename) {
struct stat st;
@@ -238,6 +245,10 @@ uptr GetListOfModules(LoadedModule *modules, uptr max_modules,
return memory_mapping.DumpListOfModules(modules, max_modules, filter);
}
+bool IsDeadlySignal(int signum) {
+ return (signum == SIGSEGV || signum == SIGBUS) && common_flags()->handle_segv;
+}
+
} // namespace __sanitizer
#endif // SANITIZER_MAC
diff --git a/lib/sanitizer_common/sanitizer_posix_libcdep.cc b/lib/sanitizer_common/sanitizer_posix_libcdep.cc
index 73b7886c2..feabc6096 100644
--- a/lib/sanitizer_common/sanitizer_posix_libcdep.cc
+++ b/lib/sanitizer_common/sanitizer_posix_libcdep.cc
@@ -16,6 +16,8 @@
#if SANITIZER_LINUX || SANITIZER_MAC
#include "sanitizer_common.h"
+#include "sanitizer_flags.h"
+#include "sanitizer_platform_limits_posix.h"
#include "sanitizer_stacktrace.h"
#include <errno.h>
@@ -117,6 +119,29 @@ void UnsetAlternateSignalStack() {
UnmapOrDie(oldstack.ss_sp, oldstack.ss_size);
}
+typedef void (*sa_sigaction_t)(int, siginfo_t *, void *);
+static void MaybeInstallSigaction(int signum,
+ SignalHandlerType handler) {
+ if (!IsDeadlySignal(signum))
+ return;
+ struct sigaction sigact;
+ internal_memset(&sigact, 0, sizeof(sigact));
+ sigact.sa_sigaction = (sa_sigaction_t)handler;
+ sigact.sa_flags = SA_SIGINFO;
+ if (common_flags()->use_sigaltstack) sigact.sa_flags |= SA_ONSTACK;
+ CHECK_EQ(0, internal_sigaction(signum, &sigact, 0));
+ VReport(1, "Installed the sigaction for signal %d\n", signum);
+}
+
+void InstallDeadlySignalHandlers(SignalHandlerType handler) {
+ // Set the alternate signal stack for the main thread.
+ // This will cause SetAlternateSignalStack to be called twice, but the stack
+ // will be actually set only once.
+ if (common_flags()->use_sigaltstack) SetAlternateSignalStack();
+ MaybeInstallSigaction(SIGSEGV, handler);
+ MaybeInstallSigaction(SIGBUS, handler);
+}
+
} // namespace __sanitizer
#endif
diff --git a/lib/sanitizer_common/sanitizer_win.cc b/lib/sanitizer_common/sanitizer_win.cc
index e3ef578a8..0424e97ee 100644
--- a/lib/sanitizer_common/sanitizer_win.cc
+++ b/lib/sanitizer_common/sanitizer_win.cc
@@ -421,6 +421,15 @@ void UnsetAlternateSignalStack() {
// FIXME: Decide what to do on Windows.
}
+void InstallDeadlySignalHandlers() {
+ // FIXME: Decide what to do on Windows.
+}
+
+bool IsDeadlySignal(int signum) {
+ // FIXME: Decide what to do on Windows.
+ return false;
+}
+
} // namespace __sanitizer
#endif // _WIN32