Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 37 additions & 12 deletions compiler-rt/lib/sanitizer_common/sanitizer_file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,17 @@ void RawWrite(const char *buffer) {

void ReportFile::ReopenIfNecessary() {
mu->CheckLocked();
if (fd == kStdoutFd || fd == kStderrFd) return;

uptr pid = internal_getpid();
if (fallbackToStderrActive && fd_pid != pid) {
// If fallbackToStderrActive is set then we fellback to stderr. If this is a
// new process, mark fd as invalid so we attempt to open again.
CHECK_EQ(fd, kStderrFd);
fd = kInvalidFd;
fallbackToStderrActive = false;
}
if (fd == kStdoutFd || fd == kStderrFd)
return;

// If in tracer, use the parent's file.
if (pid == stoptheworld_tracer_pid)
pid = stoptheworld_tracer_ppid;
Expand All @@ -48,8 +56,7 @@ void ReportFile::ReopenIfNecessary() {
// process, close it now.
if (fd_pid == pid)
return;
else
CloseFile(fd);
CloseFile(fd);
}

const char *exe_name = GetProcessName();
Expand All @@ -65,18 +72,24 @@ void ReportFile::ReopenIfNecessary() {
error_t err;
fd = OpenFile(full_path, WrOnly, &err);
if (fd == kInvalidFd) {
const char *ErrorMsgPrefix = "ERROR: Can't open file: ";
bool fallback = common_flags()->log_fallback_to_stderr;
const char *ErrorMsgPrefix =
fallback ? "WARNING: Can't open file, falling back to stderr: "
: "ERROR: Can't open file: ";
WriteToFile(kStderrFd, ErrorMsgPrefix, internal_strlen(ErrorMsgPrefix));
WriteToFile(kStderrFd, full_path, internal_strlen(full_path));
char errmsg[100];
internal_snprintf(errmsg, sizeof(errmsg), " (reason: %d)\n", err);
WriteToFile(kStderrFd, errmsg, internal_strlen(errmsg));
Die();
if (!fallback)
Die();
fallbackToStderrActive = true;
fd = kStderrFd;
}
fd_pid = pid;
}

static void RecursiveCreateParentDirs(char *path) {
static void RecursiveCreateParentDirs(char *path, fd_t &fd) {
if (path[0] == '\0')
return;
for (int i = 1; path[i] != '\0'; ++i) {
Expand All @@ -85,12 +98,19 @@ static void RecursiveCreateParentDirs(char *path) {
continue;
path[i] = '\0';
if (!DirExists(path) && !CreateDir(path)) {
const char *ErrorMsgPrefix = "ERROR: Can't create directory: ";
bool fallback = common_flags()->log_fallback_to_stderr;
const char *ErrorMsgPrefix =
fallback ? "WARNING: Can't create directory, falling back to stderr: "
: "ERROR: Can't create directory: ";
WriteToFile(kStderrFd, ErrorMsgPrefix, internal_strlen(ErrorMsgPrefix));
WriteToFile(kStderrFd, path, internal_strlen(path));
const char *ErrorMsgSuffix = "\n";
WriteToFile(kStderrFd, ErrorMsgSuffix, internal_strlen(ErrorMsgSuffix));
Die();
if (!fallback)
Die();
path[i] = save;
fd = kStderrFd;
return;
}
path[i] = save;
}
Expand Down Expand Up @@ -161,12 +181,17 @@ void ReportFile::SetReportPath(const char *path) {
if (path) {
uptr len = internal_strlen(path);
if (len > sizeof(path_prefix) - 100) {
const char *message = "ERROR: Path is too long: ";
bool fallback = common_flags()->log_fallback_to_stderr;
const char *message =
fallback ? "WARNING: Path is too long, falling back to stderr: "
: "ERROR: Path is too long: ";
WriteToFile(kStderrFd, message, internal_strlen(message));
WriteToFile(kStderrFd, path, 8);
message = "...\n";
WriteToFile(kStderrFd, message, internal_strlen(message));
Die();
if (!fallback)
Die();
path = "stderr";
}
}

Expand All @@ -180,7 +205,7 @@ void ReportFile::SetReportPath(const char *path) {
fd = kStdoutFd;
} else {
ParseAndSetPath(path, path_prefix, kMaxPathLength);
RecursiveCreateParentDirs(path_prefix);
RecursiveCreateParentDirs(path_prefix, fd);
}
}

Expand Down
3 changes: 3 additions & 0 deletions compiler-rt/lib/sanitizer_common/sanitizer_file.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ struct ReportFile {
// PID of the process that opened fd. If a fork() occurs,
// the PID of child will be different from fd_pid.
uptr fd_pid;
// Set to true if the last attempt to open the logfile failed, perhaps due to
// permission errors
bool fallbackToStderrActive = false;

private:
void ReopenIfNecessary();
Expand Down
2 changes: 2 additions & 0 deletions compiler-rt/lib/sanitizer_common/sanitizer_flags.inc
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ COMMON_FLAG(
bool, log_to_syslog, (bool)SANITIZER_ANDROID || (bool)SANITIZER_APPLE,
"Write all sanitizer output to syslog in addition to other means of "
"logging.")
COMMON_FLAG(bool, log_fallback_to_stderr, false,
"When set, fallback to stderr if we are unable to open log path.")
COMMON_FLAG(
int, verbosity, 0,
"Verbosity level (0 - silent, 1 - a bit of output, 2+ - more output).")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

// Case 1: Try setting a path that is an invalid/inaccessible directory.
// RUN: not %run %t 2>&1 | FileCheck %s --check-prefix=ERROR1
// RUN: %env_tool_opts=log_fallback_to_stderr=true %run %t 2>&1 | FileCheck %s --check-prefixes=ERROR1,FALLBACK

// Case 2: Try setting a path that is too large.
// RUN: not %run %t A 2>&1 | FileCheck %s --check-prefix=ERROR2
// RUN: %env_tool_opts=log_fallback_to_stderr=true %run %t A 2>&1 | FileCheck %s --check-prefixes=ERROR2,FALLBACK

#include <sanitizer/common_interface_defs.h>
#include <stdio.h>
Expand All @@ -14,11 +16,12 @@ int main(int argc, char **argv) {
if (argc == 1) {
// Case 1
sprintf(buff, "%s/report", argv[0]);
// ERROR1: Can't create directory: {{.*}}
// ERROR1: Can't create directory
} else {
// Case 2
snprintf(buff, sizeof(buff), "%04095d", 42);
// ERROR2: Path is too long: 00000000...
// ERROR2: Path is too long
}
__sanitizer_set_report_path(buff);
}
// FALLBACK: falling back to stderr
Loading