Skip to content

Commit 1508f59

Browse files
committed
[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
1 parent 764fed9 commit 1508f59

File tree

4 files changed

+48
-2
lines changed

4 files changed

+48
-2
lines changed

compiler-rt/include/sanitizer/common_interface_defs.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ extern "C" {
4141

4242
// Tell the tools to write their reports to "path.<pid>" instead of stderr.
4343
void __sanitizer_set_report_path(const char *path);
44+
// Tell the tools to write their reports to the provided file descriptor
45+
// (casted to void *).
46+
void __sanitizer_set_report_fd(void *fd);
4447

4548
// Notify the tools that the sandbox is going to be turned on. The reserved
4649
// parameter will be used in the future to hold a structure with functions

compiler-rt/lib/asan/asan_posix.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,9 @@ namespace __asan {
3636
void AsanOnDeadlySignal(int signo, void *siginfo, void *context) {
3737
ScopedDeadlySignal signal_scope(GetCurrentThread());
3838
int code = (int)((siginfo_t*)siginfo)->si_code;
39-
// Write the first message using the bullet-proof write.
40-
if (18 != internal_write(2, "ASAN:DEADLYSIGNAL\n", 18)) Die();
39+
// Write the first message using fd=2, just in case.
40+
// It may actually fail to write in case stderr is closed.
41+
internal_write(2, "ASAN:DEADLYSIGNAL\n", 18);
4142
SignalContext sig = SignalContext::Create(siginfo, context);
4243

4344
// Access at a reasonable offset above SP, or slightly below it (to account

compiler-rt/lib/sanitizer_common/sanitizer_common.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,11 @@ void __sanitizer_set_report_path(const char *path) {
496496
report_file.SetReportPath(path);
497497
}
498498

499+
void __sanitizer_set_report_fd(void *fd) {
500+
report_file.fd = reinterpret_cast<uptr>(fd);
501+
report_file.fd_pid = internal_getpid();
502+
}
503+
499504
void __sanitizer_report_error_summary(const char *error_summary) {
500505
Printf("%s\n", error_summary);
501506
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// Test __sanitizer_set_report_fd:
2+
// RUN: %clangxx -O2 %s -o %t
3+
// RUN: not %run %t 2>&1 | FileCheck %s
4+
// RUN: not %run %t stdout | FileCheck %s
5+
// RUN: not %run %t %t-out && FileCheck < %t-out %s
6+
7+
// REQUIRES: stable-runtime
8+
// FIXME: implement SEGV handler in other sanitizers, not just asan.
9+
// XFAIL: msan
10+
// XFAIL: lsan
11+
// XFAIL: tsan
12+
13+
#include <sanitizer/common_interface_defs.h>
14+
#include <stdio.h>
15+
#include <string.h>
16+
#include <stdlib.h>
17+
#include <sys/types.h>
18+
#include <sys/stat.h>
19+
#include <fcntl.h>
20+
#include <assert.h>
21+
22+
volatile int *null = 0;
23+
24+
int main(int argc, char **argv) {
25+
if (argc == 2) {
26+
if (!strcmp(argv[1], "stdout")) {
27+
__sanitizer_set_report_fd(reinterpret_cast<void*>(1));
28+
} else {
29+
int fd = open(argv[1], O_CREAT | O_WRONLY | O_TRUNC, S_IRWXU);
30+
assert(fd > 0);
31+
__sanitizer_set_report_fd(reinterpret_cast<void*>(fd));
32+
}
33+
}
34+
*null = 0;
35+
}
36+
37+
// CHECK: ERROR: {{.*}} SEGV on unknown address

0 commit comments

Comments
 (0)