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 | 1508f591b300128a260dfdd0cc87bab52f88c8b5 (patch) | |
| tree | 4d4f51ebf35d315d54314a02a0cb33864755d2b5 | |
| parent | 764fed98e6b038a8b633ce58308bd7987740dbc0 (diff) | |
| download | bcm5719-llvm-1508f591b300128a260dfdd0cc87bab52f88c8b5.tar.gz bcm5719-llvm-1508f591b300128a260dfdd0cc87bab52f88c8b5.zip | |
[sanitizers] introduce __sanitizer_set_report_fd so that we can re-route the sanitizer logging to another fd from inside the process
llvm-svn: 271046
4 files changed, 48 insertions, 2 deletions
diff --git a/compiler-rt/include/sanitizer/common_interface_defs.h b/compiler-rt/include/sanitizer/common_interface_defs.h index b2a4bb7b89e..0cd6e979157 100644 --- a/compiler-rt/include/sanitizer/common_interface_defs.h +++ b/compiler-rt/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/compiler-rt/lib/asan/asan_posix.cc b/compiler-rt/lib/asan/asan_posix.cc index f463c5a637c..84a29ec6a9d 100644 --- a/compiler-rt/lib/asan/asan_posix.cc +++ b/compiler-rt/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/compiler-rt/lib/sanitizer_common/sanitizer_common.cc b/compiler-rt/lib/sanitizer_common/sanitizer_common.cc index fda143e6335..e8e75dca860 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common.cc +++ b/compiler-rt/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/compiler-rt/test/sanitizer_common/TestCases/Posix/sanitizer_set_report_fd_test.cc b/compiler-rt/test/sanitizer_common/TestCases/Posix/sanitizer_set_report_fd_test.cc new file mode 100644 index 00000000000..af7eea1d7de --- /dev/null +++ b/compiler-rt/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 |

