summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorReid Kleckner <reid@kleckner.net>2013-09-05 03:19:57 +0000
committerReid Kleckner <reid@kleckner.net>2013-09-05 03:19:57 +0000
commit923bac7a85d8bd37219b440a6b4c0800ea4bcd21 (patch)
treef158bb0755f7264d8d274c05a789a00675e795ab
parentb99228de65b408b0acd9618b92774fb8add7e482 (diff)
sanitizers: Make sure Visual Studio gets error reports
Visual Studio appears to close stderr before launching a non-console win32 program. This means we don't see any sanitizer reports. If stderr printing fails, call OutputDebugStringA to get the reports into the Visual Studio debugger console. git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@190030 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/sanitizer_common/sanitizer_common.cc39
-rw-r--r--lib/sanitizer_common/sanitizer_common.h3
-rw-r--r--lib/sanitizer_common/sanitizer_posix.cc31
-rw-r--r--lib/sanitizer_common/sanitizer_win.cc18
4 files changed, 58 insertions, 33 deletions
diff --git a/lib/sanitizer_common/sanitizer_common.cc b/lib/sanitizer_common/sanitizer_common.cc
index bb601bd6a..4aab65d91 100644
--- a/lib/sanitizer_common/sanitizer_common.cc
+++ b/lib/sanitizer_common/sanitizer_common.cc
@@ -26,16 +26,19 @@ uptr GetPageSizeCached() {
return PageSize;
}
-static bool log_to_file = false; // Set to true by __sanitizer_set_report_path
// By default, dump to stderr. If |log_to_file| is true and |report_fd_pid|
// isn't equal to the current PID, try to obtain file descriptor by opening
// file "report_path_prefix.<PID>".
fd_t report_fd = kStderrFd;
-static char report_path_prefix[4096]; // Set via __sanitizer_set_report_path.
+
+// Set via __sanitizer_set_report_path.
+bool log_to_file = false;
+char report_path_prefix[sizeof(report_path_prefix)];
+
// PID of process that opened |report_fd|. If a fork() occurs, the PID of the
// child thread will be different from |report_fd_pid|.
-static uptr report_fd_pid = 0;
+uptr report_fd_pid = 0;
static DieCallbackType DieCallback;
void SetDieCallback(DieCallbackType callback) {
@@ -68,36 +71,6 @@ void NORETURN CheckFailed(const char *file, int line, const char *cond,
Die();
}
-void MaybeOpenReportFile() {
- if (!log_to_file || (report_fd_pid == internal_getpid())) return;
- InternalScopedBuffer<char> report_path_full(4096);
- internal_snprintf(report_path_full.data(), report_path_full.size(),
- "%s.%d", report_path_prefix, internal_getpid());
- uptr openrv = OpenFile(report_path_full.data(), true);
- if (internal_iserror(openrv)) {
- report_fd = kStderrFd;
- log_to_file = false;
- Report("ERROR: Can't open file: %s\n", report_path_full.data());
- Die();
- }
- if (report_fd != kInvalidFd) {
- // We're in the child. Close the parent's log.
- internal_close(report_fd);
- }
- report_fd = openrv;
- report_fd_pid = internal_getpid();
-}
-
-void RawWrite(const char *buffer) {
- static const char *kRawWriteError = "RawWrite can't output requested buffer!";
- uptr length = (uptr)internal_strlen(buffer);
- MaybeOpenReportFile();
- if (length != internal_write(report_fd, buffer, length)) {
- internal_write(report_fd, kRawWriteError, internal_strlen(kRawWriteError));
- Die();
- }
-}
-
uptr ReadFileToBuffer(const char *file_name, char **buff,
uptr *buff_size, uptr max_len) {
uptr PageSize = GetPageSizeCached();
diff --git a/lib/sanitizer_common/sanitizer_common.h b/lib/sanitizer_common/sanitizer_common.h
index 7a96a481b..abed9440b 100644
--- a/lib/sanitizer_common/sanitizer_common.h
+++ b/lib/sanitizer_common/sanitizer_common.h
@@ -116,6 +116,9 @@ void SetPrintfAndReportCallback(void (*callback)(const char *));
extern StaticSpinMutex CommonSanitizerReportMutex;
void MaybeOpenReportFile();
extern fd_t report_fd;
+extern bool log_to_file;
+extern char report_path_prefix[4096];
+extern uptr report_fd_pid;
uptr OpenFile(const char *filename, bool write);
// Opens the file 'file_name" and reads up to 'max_len' bytes.
diff --git a/lib/sanitizer_common/sanitizer_posix.cc b/lib/sanitizer_common/sanitizer_posix.cc
index 0977f2c9f..a73e7419a 100644
--- a/lib/sanitizer_common/sanitizer_posix.cc
+++ b/lib/sanitizer_common/sanitizer_posix.cc
@@ -197,6 +197,37 @@ char *FindPathToBinary(const char *name) {
return 0;
}
+void MaybeOpenReportFile() {
+ if (!log_to_file || (report_fd_pid == internal_getpid())) return;
+ InternalScopedBuffer<char> report_path_full(4096);
+ internal_snprintf(report_path_full.data(), report_path_full.size(),
+ "%s.%d", report_path_prefix, internal_getpid());
+ uptr openrv = OpenFile(report_path_full.data(), true);
+ if (internal_iserror(openrv)) {
+ report_fd = kStderrFd;
+ log_to_file = false;
+ Report("ERROR: Can't open file: %s\n", report_path_full.data());
+ Die();
+ }
+ if (report_fd != kInvalidFd) {
+ // We're in the child. Close the parent's log.
+ internal_close(report_fd);
+ }
+ report_fd = openrv;
+ report_fd_pid = internal_getpid();
+}
+
+void RawWrite(const char *buffer) {
+ static const char *kRawWriteError =
+ "RawWrite can't output requested buffer!\n";
+ uptr length = (uptr)internal_strlen(buffer);
+ MaybeOpenReportFile();
+ if (length != internal_write(report_fd, buffer, length)) {
+ internal_write(report_fd, kRawWriteError, internal_strlen(kRawWriteError));
+ Die();
+ }
+}
+
} // namespace __sanitizer
#endif // SANITIZER_LINUX || SANITIZER_MAC
diff --git a/lib/sanitizer_common/sanitizer_win.cc b/lib/sanitizer_common/sanitizer_win.cc
index c3f063fc3..4c5327ea9 100644
--- a/lib/sanitizer_common/sanitizer_win.cc
+++ b/lib/sanitizer_common/sanitizer_win.cc
@@ -398,6 +398,24 @@ void GetStackTrace(StackTrace *stack, uptr max_s, uptr pc, uptr bp,
stack->trace[i] = (uptr)tmp[i + offset];
}
+void MaybeOpenReportFile() {
+ // Windows doesn't have native fork, and we don't support Cygwin or other
+ // environments that try to fake it, so the initial report_fd will always be
+ // correct.
+}
+
+void RawWrite(const char *buffer) {
+ static const char *kRawWriteError =
+ "RawWrite can't output requested buffer!\n";
+ uptr length = (uptr)internal_strlen(buffer);
+ if (length != internal_write(report_fd, buffer, length)) {
+ // stderr may be closed, but we may be able to print to the debugger
+ // instead. This is the case when launching a program from Visual Studio,
+ // and the following routine should write to its console.
+ OutputDebugStringA(buffer);
+ }
+}
+
} // namespace __sanitizer
#endif // _WIN32