summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--compiler-rt/lib/asan/asan_internal.h2
-rw-r--r--compiler-rt/lib/asan/asan_posix.cc8
-rw-r--r--compiler-rt/lib/asan/asan_report.cc4
-rw-r--r--compiler-rt/lib/asan/asan_report.h3
-rw-r--r--compiler-rt/lib/asan/asan_rtl.cc2
-rw-r--r--compiler-rt/lib/asan/asan_win.cc4
-rw-r--r--compiler-rt/lib/asan/tests/asan_test.cc8
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_flags.inc2
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_linux.cc2
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cc1
-rw-r--r--compiler-rt/test/asan/TestCases/Posix/allow_user_segv.cc2
-rw-r--r--compiler-rt/test/sanitizer_common/TestCases/Linux/fpe.cc30
12 files changed, 53 insertions, 15 deletions
diff --git a/compiler-rt/lib/asan/asan_internal.h b/compiler-rt/lib/asan/asan_internal.h
index b4d882147f8..715559fbb7d 100644
--- a/compiler-rt/lib/asan/asan_internal.h
+++ b/compiler-rt/lib/asan/asan_internal.h
@@ -75,7 +75,7 @@ void *AsanDoesNotSupportStaticLinkage();
void AsanCheckDynamicRTPrereqs();
void AsanCheckIncompatibleRT();
-void AsanOnSIGSEGV(int, void *siginfo, void *context);
+void AsanOnDeadlySignal(int, void *siginfo, void *context);
void DisableReexec();
void MaybeReexec();
diff --git a/compiler-rt/lib/asan/asan_posix.cc b/compiler-rt/lib/asan/asan_posix.cc
index 2e857f6f624..cce56984ecd 100644
--- a/compiler-rt/lib/asan/asan_posix.cc
+++ b/compiler-rt/lib/asan/asan_posix.cc
@@ -33,11 +33,11 @@
namespace __asan {
-void AsanOnSIGSEGV(int, void *siginfo, void *context) {
+void AsanOnDeadlySignal(int signo, void *siginfo, void *context) {
ScopedDeadlySignal signal_scope(GetCurrentThread());
int code = (int)((siginfo_t*)siginfo)->si_code;
// Write the first message using the bullet-proof write.
- if (13 != internal_write(2, "ASAN:SIGSEGV\n", 13)) Die();
+ if (18 != internal_write(2, "ASAN:DEADLYSIGNAL\n", 18)) Die();
SignalContext sig = SignalContext::Create(siginfo, context);
// Access at a reasonable offset above SP, or slightly below it (to account
@@ -75,8 +75,10 @@ void AsanOnSIGSEGV(int, void *siginfo, void *context) {
// unaligned memory access.
if (IsStackAccess && (code == si_SEGV_MAPERR || code == si_SEGV_ACCERR))
ReportStackOverflow(sig);
+ else if (signo == SIGFPE)
+ ReportDeadlySignal("FPE", sig);
else
- ReportSIGSEGV("SEGV", sig);
+ ReportDeadlySignal("SEGV", sig);
}
// ---------------------- TSD ---------------- {{{1
diff --git a/compiler-rt/lib/asan/asan_report.cc b/compiler-rt/lib/asan/asan_report.cc
index c1681e64446..2d0d3b30806 100644
--- a/compiler-rt/lib/asan/asan_report.cc
+++ b/compiler-rt/lib/asan/asan_report.cc
@@ -686,7 +686,7 @@ void ReportStackOverflow(const SignalContext &sig) {
ReportErrorSummary("stack-overflow", &stack);
}
-void ReportSIGSEGV(const char *description, const SignalContext &sig) {
+void ReportDeadlySignal(const char *description, const SignalContext &sig) {
ScopedInErrorReport in_report;
Decorator d;
Printf("%s", d.Warning());
@@ -703,7 +703,7 @@ void ReportSIGSEGV(const char *description, const SignalContext &sig) {
stack.Print();
MaybeDumpInstructionBytes(sig.pc);
Printf("AddressSanitizer can not provide additional info.\n");
- ReportErrorSummary("SEGV", &stack);
+ ReportErrorSummary(description, &stack);
}
void ReportDoubleFree(uptr addr, BufferedStackTrace *free_stack) {
diff --git a/compiler-rt/lib/asan/asan_report.h b/compiler-rt/lib/asan/asan_report.h
index e2786b0f260..e971eb1d6e1 100644
--- a/compiler-rt/lib/asan/asan_report.h
+++ b/compiler-rt/lib/asan/asan_report.h
@@ -50,7 +50,8 @@ void DescribeThread(AsanThreadContext *context);
// Different kinds of error reports.
void NORETURN ReportStackOverflow(const SignalContext &sig);
-void NORETURN ReportSIGSEGV(const char *description, const SignalContext &sig);
+void NORETURN ReportDeadlySignal(const char* description,
+ const SignalContext &sig);
void NORETURN ReportNewDeleteSizeMismatch(uptr addr, uptr delete_size,
BufferedStackTrace *free_stack);
void NORETURN ReportDoubleFree(uptr addr, BufferedStackTrace *free_stack);
diff --git a/compiler-rt/lib/asan/asan_rtl.cc b/compiler-rt/lib/asan/asan_rtl.cc
index c3313e4cfa6..4fa8ea2f0bb 100644
--- a/compiler-rt/lib/asan/asan_rtl.cc
+++ b/compiler-rt/lib/asan/asan_rtl.cc
@@ -457,7 +457,7 @@ static void AsanInitInternal() {
}
AsanTSDInit(PlatformTSDDtor);
- InstallDeadlySignalHandlers(AsanOnSIGSEGV);
+ InstallDeadlySignalHandlers(AsanOnDeadlySignal);
AllocatorOptions allocator_options;
allocator_options.SetFrom(flags(), common_flags());
diff --git a/compiler-rt/lib/asan/asan_win.cc b/compiler-rt/lib/asan/asan_win.cc
index 619d2ef025e..1aec72babca 100644
--- a/compiler-rt/lib/asan/asan_win.cc
+++ b/compiler-rt/lib/asan/asan_win.cc
@@ -197,7 +197,7 @@ void ReadContextStack(void *context, uptr *stack, uptr *ssize) {
UNIMPLEMENTED();
}
-void AsanOnSIGSEGV(int, void *siginfo, void *context) {
+void AsanOnDeadlySignal(int, void *siginfo, void *context) {
UNIMPLEMENTED();
}
@@ -214,7 +214,7 @@ static long WINAPI SEHHandler(EXCEPTION_POINTERS *info) {
? "access-violation"
: "in-page-error";
SignalContext sig = SignalContext::Create(exception_record, context);
- ReportSIGSEGV(description, sig);
+ ReportDeadlySignal(description, sig);
}
// FIXME: Handle EXCEPTION_STACK_OVERFLOW here.
diff --git a/compiler-rt/lib/asan/tests/asan_test.cc b/compiler-rt/lib/asan/tests/asan_test.cc
index 07d59e09a72..6644a094973 100644
--- a/compiler-rt/lib/asan/tests/asan_test.cc
+++ b/compiler-rt/lib/asan/tests/asan_test.cc
@@ -250,12 +250,12 @@ TEST(AddressSanitizer, BitFieldNegativeTest) {
#if ASAN_NEEDS_SEGV
namespace {
-const char kUnknownCrash[] = "AddressSanitizer: SEGV on unknown address";
+const char kSEGVCrash[] = "AddressSanitizer: SEGV on unknown address";
const char kOverriddenHandler[] = "ASan signal handler has been overridden\n";
TEST(AddressSanitizer, WildAddressTest) {
char *c = (char*)0x123;
- EXPECT_DEATH(*c = 0, kUnknownCrash);
+ EXPECT_DEATH(*c = 0, kSEGVCrash);
}
void my_sigaction_sighandler(int, siginfo_t*, void*) {
@@ -279,10 +279,10 @@ TEST(AddressSanitizer, SignalTest) {
EXPECT_EQ(0, sigaction(SIGBUS, &sigact, 0));
#endif
char *c = (char*)0x123;
- EXPECT_DEATH(*c = 0, kUnknownCrash);
+ EXPECT_DEATH(*c = 0, kSEGVCrash);
// ... and signal().
EXPECT_EQ(0, signal(SIGSEGV, my_signal_sighandler));
- EXPECT_DEATH(*c = 0, kUnknownCrash);
+ EXPECT_DEATH(*c = 0, kSEGVCrash);
}
} // namespace
#endif
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc b/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc
index 521be7dcc90..80931338c3c 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc
@@ -78,6 +78,8 @@ COMMON_FLAG(bool, handle_segv, SANITIZER_NEEDS_SEGV,
"If set, registers the tool's custom SIGSEGV/SIGBUS handler.")
COMMON_FLAG(bool, handle_abort, false,
"If set, registers the tool's custom SIGABRT handler.")
+COMMON_FLAG(bool, handle_sigfpe, true,
+ "If set, registers the tool's custom SIGFPE handler.")
COMMON_FLAG(bool, allow_user_segv_handler, false,
"If set, allows user to register a SEGV handler even if the tool "
"registers one.")
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc
index 3da165dc5cc..3094f114fb9 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc
@@ -1034,6 +1034,8 @@ AndroidApiLevel AndroidGetApiLevel() {
bool IsDeadlySignal(int signum) {
if (common_flags()->handle_abort && signum == SIGABRT)
return true;
+ if (common_flags()->handle_sigfpe && signum == SIGFPE)
+ return true;
return (signum == SIGSEGV || signum == SIGBUS) && common_flags()->handle_segv;
}
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cc b/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cc
index 14b58564964..b9b7e5070a1 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cc
@@ -188,6 +188,7 @@ void InstallDeadlySignalHandlers(SignalHandlerType handler) {
MaybeInstallSigaction(SIGSEGV, handler);
MaybeInstallSigaction(SIGBUS, handler);
MaybeInstallSigaction(SIGABRT, handler);
+ MaybeInstallSigaction(SIGFPE, handler);
}
#endif // SANITIZER_GO
diff --git a/compiler-rt/test/asan/TestCases/Posix/allow_user_segv.cc b/compiler-rt/test/asan/TestCases/Posix/allow_user_segv.cc
index b299ae8cb21..ecb3a894ffd 100644
--- a/compiler-rt/test/asan/TestCases/Posix/allow_user_segv.cc
+++ b/compiler-rt/test/asan/TestCases/Posix/allow_user_segv.cc
@@ -55,5 +55,5 @@ int main() {
// CHECK: User sigaction installed
// CHECK-NEXT: User sigaction called
-// CHECK-NEXT: ASAN:SIGSEGV
+// CHECK-NEXT: ASAN:DEADLYSIGNAL
// CHECK: AddressSanitizer: SEGV on unknown address
diff --git a/compiler-rt/test/sanitizer_common/TestCases/Linux/fpe.cc b/compiler-rt/test/sanitizer_common/TestCases/Linux/fpe.cc
new file mode 100644
index 00000000000..988899daf90
--- /dev/null
+++ b/compiler-rt/test/sanitizer_common/TestCases/Linux/fpe.cc
@@ -0,0 +1,30 @@
+// Test the handle_sigfpe option.
+// RUN: %clang %s -o %t
+// RUN: not %run %t 2>&1 | FileCheck --check-prefix=CHECK1 %s
+// RUN: %tool_options=handle_sigfpe=0 not --crash %run %t 2>&1 | FileCheck --check-prefix=CHECK0 %s
+// RUN: %tool_options=handle_sigfpe=1 not %run %t 2>&1 | FileCheck --check-prefix=CHECK1 %s
+// FIXME: implement in other sanitizers, not just asan.
+// XFAIL: msan
+// XFAIL: lsan
+// XFAIL: tsan
+//
+// FIXME: seems to fail on ARM
+// REQUIRES: x86_64-supported-target
+#include <assert.h>
+#include <stdio.h>
+#include <sanitizer/asan_interface.h>
+
+void death() {
+ fprintf(stderr, "DEATH CALLBACK\n");
+}
+
+int main(int argc, char **argv) {
+ __sanitizer_set_death_callback(death);
+ volatile int one = 1;
+ volatile int zero = 0;
+ volatile int sink;
+ sink = one / zero;
+}
+// CHECK1: ERROR: {{.*}}Sanitizer:
+// CHECK1: DEATH CALLBACK
+// CHECK0-NOT: Sanitizer
OpenPOWER on IntegriCloud