summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/asan/tests/asan_test.cc2
-rw-r--r--lib/sanitizer_common/sanitizer_flags.inc4
-rw-r--r--lib/sanitizer_common/sanitizer_linux.cc4
-rw-r--r--lib/sanitizer_common/sanitizer_mac.cc4
-rw-r--r--lib/sanitizer_common/sanitizer_posix.cc4
-rw-r--r--test/asan/TestCases/Posix/asan-sigbus.cpp40
6 files changed, 53 insertions, 5 deletions
diff --git a/lib/asan/tests/asan_test.cc b/lib/asan/tests/asan_test.cc
index 424a79e00..7bc230afa 100644
--- a/lib/asan/tests/asan_test.cc
+++ b/lib/asan/tests/asan_test.cc
@@ -945,7 +945,7 @@ TEST(AddressSanitizer, ShadowGapTest) {
char *addr = (char*)0x0000100000080000;
# endif
#endif
- EXPECT_DEATH(*addr = 1, "AddressSanitizer: SEGV on unknown");
+ EXPECT_DEATH(*addr = 1, "AddressSanitizer: BUS on unknown");
}
#endif // ASAN_NEEDS_SEGV
diff --git a/lib/sanitizer_common/sanitizer_flags.inc b/lib/sanitizer_common/sanitizer_flags.inc
index d799f6ef7..1306c721b 100644
--- a/lib/sanitizer_common/sanitizer_flags.inc
+++ b/lib/sanitizer_common/sanitizer_flags.inc
@@ -80,7 +80,9 @@ COMMON_FLAG(int, print_module_map, 0,
"exits, 2 = print after each report.")
COMMON_FLAG(bool, check_printf, true, "Check printf arguments.")
COMMON_FLAG(bool, handle_segv, true,
- "If set, registers the tool's custom SIGSEGV/SIGBUS handler.")
+ "If set, registers the tool's custom SIGSEGV handler.")
+COMMON_FLAG(bool, handle_sigbus, true,
+ "If set, registers the tool's custom SIGBUS handler.")
COMMON_FLAG(bool, handle_abort, false,
"If set, registers the tool's custom SIGABRT handler.")
COMMON_FLAG(bool, handle_sigill, false,
diff --git a/lib/sanitizer_common/sanitizer_linux.cc b/lib/sanitizer_common/sanitizer_linux.cc
index 5f84dc511..46dd0858a 100644
--- a/lib/sanitizer_common/sanitizer_linux.cc
+++ b/lib/sanitizer_common/sanitizer_linux.cc
@@ -1292,7 +1292,9 @@ bool IsHandledDeadlySignal(int signum) {
return true;
if (common_flags()->handle_sigfpe && signum == SIGFPE)
return true;
- return (signum == SIGSEGV || signum == SIGBUS) && common_flags()->handle_segv;
+ if (common_flags()->handle_segv && signum == SIGSEGV)
+ return true;
+ return common_flags()->handle_sigbus && signum == SIGBUS;
}
#if !SANITIZER_GO
diff --git a/lib/sanitizer_common/sanitizer_mac.cc b/lib/sanitizer_common/sanitizer_mac.cc
index 8101d9515..7e85505a6 100644
--- a/lib/sanitizer_common/sanitizer_mac.cc
+++ b/lib/sanitizer_common/sanitizer_mac.cc
@@ -404,7 +404,9 @@ bool IsHandledDeadlySignal(int signum) {
return true;
if (common_flags()->handle_sigfpe && signum == SIGFPE)
return true;
- return (signum == SIGSEGV || signum == SIGBUS) && common_flags()->handle_segv;
+ if (common_flags()->handle_segv && signum == SIGSEGV)
+ return true;
+ return common_flags()->handle_sigbus && signum == SIGBUS;
}
MacosVersion cached_macos_version = MACOS_VERSION_UNINITIALIZED;
diff --git a/lib/sanitizer_common/sanitizer_posix.cc b/lib/sanitizer_common/sanitizer_posix.cc
index b9cfb06bb..9916f4d38 100644
--- a/lib/sanitizer_common/sanitizer_posix.cc
+++ b/lib/sanitizer_common/sanitizer_posix.cc
@@ -366,8 +366,10 @@ const char *DescribeSignalOrException(int signo) {
return "ILL";
case SIGABRT:
return "ABRT";
- default:
+ case SIGSEGV:
return "SEGV";
+ case SIGBUS:
+ return "BUS";
}
return "UNKNOWN SIGNAL";
}
diff --git a/test/asan/TestCases/Posix/asan-sigbus.cpp b/test/asan/TestCases/Posix/asan-sigbus.cpp
new file mode 100644
index 000000000..e07392b4c
--- /dev/null
+++ b/test/asan/TestCases/Posix/asan-sigbus.cpp
@@ -0,0 +1,40 @@
+// Check handle_bus flag
+// Defaults to true
+// RUN: %clangxx_asan -std=c++11 %s -o %t
+// RUN: not %run %t %T/file 2>&1 | FileCheck %s -check-prefix=CHECK-BUS
+// RUN: %env_asan_opts=handle_sigbus=false not --crash %run %t %T/file 2>&1 | FileCheck %s
+
+#include <assert.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+char array[4096];
+int main(int argc, char **argv) {
+ assert(argc > 1);
+ int fd = open(argv[1], O_RDWR | O_CREAT, 0700);
+ if (fd < 0) {
+ perror("open");
+ exit(1);
+ }
+ assert(write(fd, array, sizeof(array)) == sizeof(array));
+
+ // Write some zeroes to the file, then mmap it while it has a 4KiB size
+ char *addr = (char *)mmap(nullptr, sizeof(array), PROT_READ,
+ MAP_FILE | MAP_SHARED, fd, 0);
+ if (addr == MAP_FAILED) {
+ perror("mmap");
+ exit(1);
+ }
+
+ // Truncate the file so our memory isn't valid any more
+ assert(ftruncate(fd, 0) == 0);
+
+ // Try to access the memory
+ return addr[42];
+ // CHECK-NOT: DEADLYSIGNAL
+ // CHECK-BUS: DEADLYSIGNAL
+ // CHECK-BUS: ERROR: AddressSanitizer: BUS
+}