summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKostya Serebryany <kcc@google.com>2016-05-27 21:23:05 +0000
committerKostya Serebryany <kcc@google.com>2016-05-27 21:23:05 +0000
commitf4e2d7d1d4a64b8e374fde6e87047347831adf13 (patch)
treec94e64361a75866068cf2587aec6580cd8237f55
parent6e2868a6ca252fd9fcf4cf1fab76dc5cc8b9258e (diff)
[sanitizers] introduce __sanitizer_set_report_fd so that we can re-route the sanitizer logging to another fd from inside the process
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@271046 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/sanitizer/common_interface_defs.h3
-rw-r--r--lib/asan/asan_posix.cc5
-rw-r--r--lib/sanitizer_common/sanitizer_common.cc5
-rw-r--r--test/sanitizer_common/TestCases/Posix/sanitizer_set_report_fd_test.cc37
4 files changed, 48 insertions, 2 deletions
diff --git a/include/sanitizer/common_interface_defs.h b/include/sanitizer/common_interface_defs.h
index b2a4bb7b8..0cd6e9791 100644
--- a/include/sanitizer/common_interface_defs.h
+++ b/include/sanitizer/common_interface_defs.h
@@ -41,6 +41,9 @@ extern "C" {
// Tell the tools to write their reports to "path.<pid>" instead of stderr.
void __sanitizer_set_report_path(const char *path);
+ // Tell the tools to write their reports to the provided file descriptor
+ // (casted to void *).
+ void __sanitizer_set_report_fd(void *fd);
// Notify the tools that the sandbox is going to be turned on. The reserved
// parameter will be used in the future to hold a structure with functions
diff --git a/lib/asan/asan_posix.cc b/lib/asan/asan_posix.cc
index f463c5a63..84a29ec6a 100644
--- a/lib/asan/asan_posix.cc
+++ b/lib/asan/asan_posix.cc
@@ -36,8 +36,9 @@ namespace __asan {
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 (18 != internal_write(2, "ASAN:DEADLYSIGNAL\n", 18)) Die();
+ // Write the first message using fd=2, just in case.
+ // It may actually fail to write in case stderr is closed.
+ internal_write(2, "ASAN:DEADLYSIGNAL\n", 18);
SignalContext sig = SignalContext::Create(siginfo, context);
// Access at a reasonable offset above SP, or slightly below it (to account
diff --git a/lib/sanitizer_common/sanitizer_common.cc b/lib/sanitizer_common/sanitizer_common.cc
index fda143e63..e8e75dca8 100644
--- a/lib/sanitizer_common/sanitizer_common.cc
+++ b/lib/sanitizer_common/sanitizer_common.cc
@@ -496,6 +496,11 @@ void __sanitizer_set_report_path(const char *path) {
report_file.SetReportPath(path);
}
+void __sanitizer_set_report_fd(void *fd) {
+ report_file.fd = reinterpret_cast<uptr>(fd);
+ report_file.fd_pid = internal_getpid();
+}
+
void __sanitizer_report_error_summary(const char *error_summary) {
Printf("%s\n", error_summary);
}
diff --git a/test/sanitizer_common/TestCases/Posix/sanitizer_set_report_fd_test.cc b/test/sanitizer_common/TestCases/Posix/sanitizer_set_report_fd_test.cc
new file mode 100644
index 000000000..af7eea1d7
--- /dev/null
+++ b/test/sanitizer_common/TestCases/Posix/sanitizer_set_report_fd_test.cc
@@ -0,0 +1,37 @@
+// Test __sanitizer_set_report_fd:
+// RUN: %clangxx -O2 %s -o %t
+// RUN: not %run %t 2>&1 | FileCheck %s
+// RUN: not %run %t stdout | FileCheck %s
+// RUN: not %run %t %t-out && FileCheck < %t-out %s
+
+// REQUIRES: stable-runtime
+// FIXME: implement SEGV handler in other sanitizers, not just asan.
+// XFAIL: msan
+// XFAIL: lsan
+// XFAIL: tsan
+
+#include <sanitizer/common_interface_defs.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <assert.h>
+
+volatile int *null = 0;
+
+int main(int argc, char **argv) {
+ if (argc == 2) {
+ if (!strcmp(argv[1], "stdout")) {
+ __sanitizer_set_report_fd(reinterpret_cast<void*>(1));
+ } else {
+ int fd = open(argv[1], O_CREAT | O_WRONLY | O_TRUNC, S_IRWXU);
+ assert(fd > 0);
+ __sanitizer_set_report_fd(reinterpret_cast<void*>(fd));
+ }
+ }
+ *null = 0;
+}
+
+// CHECK: ERROR: {{.*}} SEGV on unknown address