diff options
author | Kostya Serebryany <kcc@google.com> | 2016-05-27 21:23:05 +0000 |
---|---|---|
committer | Kostya Serebryany <kcc@google.com> | 2016-05-27 21:23:05 +0000 |
commit | f4e2d7d1d4a64b8e374fde6e87047347831adf13 (patch) | |
tree | c94e64361a75866068cf2587aec6580cd8237f55 | |
parent | 6e2868a6ca252fd9fcf4cf1fab76dc5cc8b9258e (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.h | 3 | ||||
-rw-r--r-- | lib/asan/asan_posix.cc | 5 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_common.cc | 5 | ||||
-rw-r--r-- | test/sanitizer_common/TestCases/Posix/sanitizer_set_report_fd_test.cc | 37 |
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 |