Index: lib/asan/asan_report.cc =================================================================== --- lib/asan/asan_report.cc +++ lib/asan/asan_report.cc @@ -141,9 +141,9 @@ // Can't use Report() here because of potential deadlocks // in nested signal handlers. - const char msg[] = "AddressSanitizer: nested bug in the same thread, " - "aborting.\n"; - WriteToFile(kStderrFd, msg, sizeof(msg)); + static const char msg[] = + "AddressSanitizer: nested bug in the same thread, aborting.\n"; + CatastrophicErrorWrite(msg, sizeof(msg) - 1); internal__exit(common_flags()->exitcode); } Index: lib/dfsan/dfsan.cc =================================================================== --- lib/dfsan/dfsan.cc +++ lib/dfsan/dfsan.cc @@ -21,6 +21,7 @@ #include "sanitizer_common/sanitizer_atomic.h" #include "sanitizer_common/sanitizer_common.h" +#include "sanitizer_common/sanitizer_file.h" #include "sanitizer_common/sanitizer_flags.h" #include "sanitizer_common/sanitizer_flag_parser.h" #include "sanitizer_common/sanitizer_libc.h" Index: lib/sanitizer_common/CMakeLists.txt =================================================================== --- lib/sanitizer_common/CMakeLists.txt +++ lib/sanitizer_common/CMakeLists.txt @@ -7,6 +7,7 @@ sanitizer_deadlock_detector1.cc sanitizer_deadlock_detector2.cc sanitizer_errno.cc + sanitizer_file.cc sanitizer_flags.cc sanitizer_flag_parser.cc sanitizer_libc.cc Index: lib/sanitizer_common/sanitizer_common.h =================================================================== --- lib/sanitizer_common/sanitizer_common.h +++ lib/sanitizer_common/sanitizer_common.h @@ -185,6 +185,7 @@ void SetLowLevelAllocateCallback(LowLevelAllocateCallback callback); // IO +void CatastrophicErrorWrite(const char *buffer, uptr length); void RawWrite(const char *buffer); bool ColorizeReports(); void RemoveANSIEscapeSequencesFromString(char *buffer); @@ -203,64 +204,9 @@ // Can be used to prevent mixing error reports from different sanitizers. extern StaticSpinMutex CommonSanitizerReportMutex; -struct ReportFile { - void Write(const char *buffer, uptr length); - bool SupportsColors(); - void SetReportPath(const char *path); - - // Don't use fields directly. They are only declared public to allow - // aggregate initialization. - - // Protects fields below. - StaticSpinMutex *mu; - // Opened file descriptor. Defaults to stderr. It may be equal to - // kInvalidFd, in which case new file will be opened when necessary. - fd_t fd; - // Path prefix of report file, set via __sanitizer_set_report_path. - char path_prefix[kMaxPathLength]; - // Full path to report, obtained as .PID - char full_path[kMaxPathLength]; - // PID of the process that opened fd. If a fork() occurs, - // the PID of child will be different from fd_pid. - uptr fd_pid; - - private: - void ReopenIfNecessary(); -}; -extern ReportFile report_file; - extern uptr stoptheworld_tracer_pid; extern uptr stoptheworld_tracer_ppid; -enum FileAccessMode { - RdOnly, - WrOnly, - RdWr -}; - -// Returns kInvalidFd on error. -fd_t OpenFile(const char *filename, FileAccessMode mode, - error_t *errno_p = nullptr); -void CloseFile(fd_t); - -// Return true on success, false on error. -bool ReadFromFile(fd_t fd, void *buff, uptr buff_size, - uptr *bytes_read = nullptr, error_t *error_p = nullptr); -bool WriteToFile(fd_t fd, const void *buff, uptr buff_size, - uptr *bytes_written = nullptr, error_t *error_p = nullptr); - -bool RenameFile(const char *oldpath, const char *newpath, - error_t *error_p = nullptr); - -// Scoped file handle closer. -struct FileCloser { - explicit FileCloser(fd_t fd) : fd(fd) {} - ~FileCloser() { CloseFile(fd); } - fd_t fd; -}; - -bool SupportsColoredOutput(fd_t fd); - // Opens the file 'file_name" and reads up to 'max_len' bytes. // The resulting buffer is mmaped and stored in '*buff'. // The size of the mmaped region is stored in '*buff_size'. @@ -269,11 +215,6 @@ bool ReadFileToBuffer(const char *file_name, char **buff, uptr *buff_size, uptr *read_len, uptr max_len = 1 << 26, error_t *errno_p = nullptr); -// Maps given file to virtual memory, and returns pointer to it -// (or NULL if mapping fails). Stores the size of mmaped region -// in '*buff_size'. -void *MapFileToMemory(const char *file_name, uptr *buff_size); -void *MapWritableFileToMemory(void *addr, uptr size, fd_t fd, OFF_T offset); bool IsAccessibleMemoryRange(uptr beg, uptr size); @@ -293,27 +234,8 @@ void DisableCoreDumperIfNecessary(); void DumpProcessMap(); void PrintModuleMap(); -bool FileExists(const char *filename); const char *GetEnv(const char *name); bool SetEnv(const char *name, const char *value); -const char *GetPwd(); -char *FindPathToBinary(const char *name); -bool IsPathSeparator(const char c); -bool IsAbsolutePath(const char *path); -// Starts a subprocess and returs its pid. -// If *_fd parameters are not kInvalidFd their corresponding input/output -// streams will be redirect to the file. The files will always be closed -// in parent process even in case of an error. -// The child process will close all fds after STDERR_FILENO -// before passing control to a program. -pid_t StartSubprocess(const char *filename, const char *const argv[], - fd_t stdin_fd = kInvalidFd, fd_t stdout_fd = kInvalidFd, - fd_t stderr_fd = kInvalidFd); -// Checks if specified process is still running -bool IsProcessRunning(pid_t pid); -// Waits for the process to finish and returns its exit code. -// Returns -1 in case of an error. -int WaitForProcess(pid_t pid); u32 GetUid(); void ReExec(); Index: lib/sanitizer_common/sanitizer_common.cc =================================================================== --- lib/sanitizer_common/sanitizer_common.cc +++ lib/sanitizer_common/sanitizer_common.cc @@ -27,72 +27,6 @@ atomic_uint32_t current_verbosity; uptr PageSizeCached; -StaticSpinMutex report_file_mu; -ReportFile report_file = {&report_file_mu, kStderrFd, "", "", 0}; - -void RawWrite(const char *buffer) { - report_file.Write(buffer, internal_strlen(buffer)); -} - -void ReportFile::ReopenIfNecessary() { - mu->CheckLocked(); - if (fd == kStdoutFd || fd == kStderrFd) return; - - uptr pid = internal_getpid(); - // If in tracer, use the parent's file. - if (pid == stoptheworld_tracer_pid) - pid = stoptheworld_tracer_ppid; - if (fd != kInvalidFd) { - // If the report file is already opened by the current process, - // do nothing. Otherwise the report file was opened by the parent - // process, close it now. - if (fd_pid == pid) - return; - else - CloseFile(fd); - } - - const char *exe_name = GetProcessName(); - if (common_flags()->log_exe_name && exe_name) { - internal_snprintf(full_path, kMaxPathLength, "%s.%s.%zu", path_prefix, - exe_name, pid); - } else { - internal_snprintf(full_path, kMaxPathLength, "%s.%zu", path_prefix, pid); - } - fd = OpenFile(full_path, WrOnly); - if (fd == kInvalidFd) { - const char *ErrorMsgPrefix = "ERROR: Can't open file: "; - WriteToFile(kStderrFd, ErrorMsgPrefix, internal_strlen(ErrorMsgPrefix)); - WriteToFile(kStderrFd, full_path, internal_strlen(full_path)); - Die(); - } - fd_pid = pid; -} - -void ReportFile::SetReportPath(const char *path) { - if (!path) - return; - uptr len = internal_strlen(path); - if (len > sizeof(path_prefix) - 100) { - Report("ERROR: Path is too long: %c%c%c%c%c%c%c%c...\n", - path[0], path[1], path[2], path[3], - path[4], path[5], path[6], path[7]); - Die(); - } - - SpinMutexLock l(mu); - if (fd != kStdoutFd && fd != kStderrFd && fd != kInvalidFd) - CloseFile(fd); - fd = kInvalidFd; - if (internal_strcmp(path, "stdout") == 0) { - fd = kStdoutFd; - } else if (internal_strcmp(path, "stderr") == 0) { - fd = kStderrFd; - } else { - internal_snprintf(path_prefix, kMaxPathLength, "%s", path); - } -} - // PID of the tracer task in StopTheWorld. It shares the address space with the // main process, but has a different PID and thus requires special handling. uptr stoptheworld_tracer_pid = 0; @@ -120,42 +54,6 @@ UNREACHABLE("unable to mmap"); } -bool ReadFileToBuffer(const char *file_name, char **buff, uptr *buff_size, - uptr *read_len, uptr max_len, error_t *errno_p) { - uptr PageSize = GetPageSizeCached(); - uptr kMinFileLen = PageSize; - *buff = nullptr; - *buff_size = 0; - *read_len = 0; - // The files we usually open are not seekable, so try different buffer sizes. - for (uptr size = kMinFileLen; size <= max_len; size *= 2) { - fd_t fd = OpenFile(file_name, RdOnly, errno_p); - if (fd == kInvalidFd) return false; - UnmapOrDie(*buff, *buff_size); - *buff = (char*)MmapOrDie(size, __func__); - *buff_size = size; - *read_len = 0; - // Read up to one page at a time. - bool reached_eof = false; - while (*read_len + PageSize <= size) { - uptr just_read; - if (!ReadFromFile(fd, *buff + *read_len, PageSize, &just_read, errno_p)) { - UnmapOrDie(*buff, *buff_size); - return false; - } - if (just_read == 0) { - reached_eof = true; - break; - } - *read_len += just_read; - } - CloseFile(fd); - if (reached_eof) // We've read the whole file. - break; - } - return true; -} - typedef bool UptrComparisonFunction(const uptr &a, const uptr &b); typedef bool U32ComparisonFunction(const u32 &a, const u32 &b); @@ -360,36 +258,6 @@ return true; } -static const char kPathSeparator = SANITIZER_WINDOWS ? ';' : ':'; - -char *FindPathToBinary(const char *name) { - if (FileExists(name)) { - return internal_strdup(name); - } - - const char *path = GetEnv("PATH"); - if (!path) - return nullptr; - uptr name_len = internal_strlen(name); - InternalScopedBuffer buffer(kMaxPathLength); - const char *beg = path; - while (true) { - const char *end = internal_strchrnul(beg, kPathSeparator); - uptr prefix_len = end - beg; - if (prefix_len + name_len + 2 <= kMaxPathLength) { - internal_memcpy(buffer.data(), beg, prefix_len); - buffer[prefix_len] = '/'; - internal_memcpy(&buffer[prefix_len + 1], name, name_len); - buffer[prefix_len + 1 + name_len] = '\0'; - if (FileExists(buffer.data())) - return internal_strdup(buffer.data()); - } - if (*end == '\0') break; - beg = end + 1; - } - return nullptr; -} - static char binary_name_cache_str[kMaxPathLength]; static char process_name_cache_str[kMaxPathLength]; @@ -483,15 +351,6 @@ using namespace __sanitizer; // NOLINT extern "C" { -void __sanitizer_set_report_path(const char *path) { - report_file.SetReportPath(path); -} - -void __sanitizer_set_report_fd(void *fd) { - report_file.fd = (fd_t)reinterpret_cast(fd); - report_file.fd_pid = internal_getpid(); -} - SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_report_error_summary, const char *error_summary) { Printf("%s\n", error_summary); Index: lib/sanitizer_common/sanitizer_common_libcdep.cc =================================================================== --- lib/sanitizer_common/sanitizer_common_libcdep.cc +++ lib/sanitizer_common/sanitizer_common_libcdep.cc @@ -14,6 +14,7 @@ #include "sanitizer_common.h" #include "sanitizer_allocator_interface.h" +#include "sanitizer_file.h" #include "sanitizer_flags.h" #include "sanitizer_stackdepot.h" #include "sanitizer_stacktrace.h" Index: lib/sanitizer_common/sanitizer_coverage_libcdep_new.cc =================================================================== --- lib/sanitizer_common/sanitizer_coverage_libcdep_new.cc +++ lib/sanitizer_common/sanitizer_coverage_libcdep_new.cc @@ -12,6 +12,7 @@ #include "sanitizer_allocator_internal.h" #include "sanitizer_atomic.h" #include "sanitizer_common.h" +#include "sanitizer_file.h" #include "sanitizer_symbolizer.h" using namespace __sanitizer; Index: lib/sanitizer_common/sanitizer_file.h =================================================================== --- /dev/null +++ lib/sanitizer_common/sanitizer_file.h @@ -0,0 +1,107 @@ +//===-- sanitizer_file.h ---------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===---------------------------------------------------------------------===// +// +// This file is shared between run-time libraries of sanitizers. +// +//===---------------------------------------------------------------------===// +#ifndef SANITIZER_FILE_H +#define SANITIZER_FILE_H + +#include "sanitizer_interface_internal.h" +#include "sanitizer_internal_defs.h" +#include "sanitizer_libc.h" +#include "sanitizer_mutex.h" + +namespace __sanitizer { + +struct ReportFile { + void Write(const char *buffer, uptr length); + bool SupportsColors(); + void SetReportPath(const char *path); + + // Don't use fields directly. They are only declared public to allow + // aggregate initialization. + + // Protects fields below. + StaticSpinMutex *mu; + // Opened file descriptor. Defaults to stderr. It may be equal to + // kInvalidFd, in which case new file will be opened when necessary. + fd_t fd; + // Path prefix of report file, set via __sanitizer_set_report_path. + char path_prefix[kMaxPathLength]; + // Full path to report, obtained as .PID + char full_path[kMaxPathLength]; + // PID of the process that opened fd. If a fork() occurs, + // the PID of child will be different from fd_pid. + uptr fd_pid; + + private: + void ReopenIfNecessary(); +}; +extern ReportFile report_file; + +enum FileAccessMode { + RdOnly, + WrOnly, + RdWr +}; + +// Returns kInvalidFd on error. +fd_t OpenFile(const char *filename, FileAccessMode mode, + error_t *errno_p = nullptr); +void CloseFile(fd_t); + +// Return true on success, false on error. +bool ReadFromFile(fd_t fd, void *buff, uptr buff_size, + uptr *bytes_read = nullptr, error_t *error_p = nullptr); +bool WriteToFile(fd_t fd, const void *buff, uptr buff_size, + uptr *bytes_written = nullptr, error_t *error_p = nullptr); + +bool RenameFile(const char *oldpath, const char *newpath, + error_t *error_p = nullptr); + +// Scoped file handle closer. +struct FileCloser { + explicit FileCloser(fd_t fd) : fd(fd) {} + ~FileCloser() { CloseFile(fd); } + fd_t fd; +}; + +bool SupportsColoredOutput(fd_t fd); + +// OS +const char *GetPwd(); +bool FileExists(const char *filename); +char *FindPathToBinary(const char *name); +bool IsPathSeparator(const char c); +bool IsAbsolutePath(const char *path); +// Starts a subprocess and returs its pid. +// If *_fd parameters are not kInvalidFd their corresponding input/output +// streams will be redirect to the file. The files will always be closed +// in parent process even in case of an error. +// The child process will close all fds after STDERR_FILENO +// before passing control to a program. +pid_t StartSubprocess(const char *filename, const char *const argv[], + fd_t stdin_fd = kInvalidFd, fd_t stdout_fd = kInvalidFd, + fd_t stderr_fd = kInvalidFd); +// Checks if specified process is still running +bool IsProcessRunning(pid_t pid); +// Waits for the process to finish and returns its exit code. +// Returns -1 in case of an error. +int WaitForProcess(pid_t pid); + +// Maps given file to virtual memory, and returns pointer to it +// (or NULL if mapping fails). Stores the size of mmaped region +// in '*buff_size'. +void *MapFileToMemory(const char *file_name, uptr *buff_size); +void *MapWritableFileToMemory(void *addr, uptr size, fd_t fd, OFF_T offset); + +} // namespace __sanitizer + +#endif // SANITIZER_FILE_H Index: lib/sanitizer_common/sanitizer_file.cc =================================================================== --- /dev/null +++ lib/sanitizer_common/sanitizer_file.cc @@ -0,0 +1,168 @@ +//===-- sanitizer_file.cc ------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===---------------------------------------------------------------------===// +// +// This file is shared between AddressSanitizer and ThreadSanitizer +// run-time libraries. +//===---------------------------------------------------------------------===// + +#include "sanitizer_common.h" +#include "sanitizer_file.h" + +namespace __sanitizer { + +void CatastrophicErrorWrite(const char *buffer, uptr length) { + WriteToFile(kStderrFd, buffer, length); +} + +StaticSpinMutex report_file_mu; +ReportFile report_file = {&report_file_mu, kStderrFd, "", "", 0}; + +void RawWrite(const char *buffer) { + report_file.Write(buffer, internal_strlen(buffer)); +} + +void ReportFile::ReopenIfNecessary() { + mu->CheckLocked(); + if (fd == kStdoutFd || fd == kStderrFd) return; + + uptr pid = internal_getpid(); + // If in tracer, use the parent's file. + if (pid == stoptheworld_tracer_pid) + pid = stoptheworld_tracer_ppid; + if (fd != kInvalidFd) { + // If the report file is already opened by the current process, + // do nothing. Otherwise the report file was opened by the parent + // process, close it now. + if (fd_pid == pid) + return; + else + CloseFile(fd); + } + + const char *exe_name = GetProcessName(); + if (common_flags()->log_exe_name && exe_name) { + internal_snprintf(full_path, kMaxPathLength, "%s.%s.%zu", path_prefix, + exe_name, pid); + } else { + internal_snprintf(full_path, kMaxPathLength, "%s.%zu", path_prefix, pid); + } + fd = OpenFile(full_path, WrOnly); + if (fd == kInvalidFd) { + const char *ErrorMsgPrefix = "ERROR: Can't open file: "; + WriteToFile(kStderrFd, ErrorMsgPrefix, internal_strlen(ErrorMsgPrefix)); + WriteToFile(kStderrFd, full_path, internal_strlen(full_path)); + Die(); + } + fd_pid = pid; +} + +void ReportFile::SetReportPath(const char *path) { + if (!path) + return; + uptr len = internal_strlen(path); + if (len > sizeof(path_prefix) - 100) { + Report("ERROR: Path is too long: %c%c%c%c%c%c%c%c...\n", + path[0], path[1], path[2], path[3], + path[4], path[5], path[6], path[7]); + Die(); + } + + SpinMutexLock l(mu); + if (fd != kStdoutFd && fd != kStderrFd && fd != kInvalidFd) + CloseFile(fd); + fd = kInvalidFd; + if (internal_strcmp(path, "stdout") == 0) { + fd = kStdoutFd; + } else if (internal_strcmp(path, "stderr") == 0) { + fd = kStderrFd; + } else { + internal_snprintf(path_prefix, kMaxPathLength, "%s", path); + } +} + +bool ReadFileToBuffer(const char *file_name, char **buff, uptr *buff_size, + uptr *read_len, uptr max_len, error_t *errno_p) { + uptr PageSize = GetPageSizeCached(); + uptr kMinFileLen = PageSize; + *buff = nullptr; + *buff_size = 0; + *read_len = 0; + // The files we usually open are not seekable, so try different buffer sizes. + for (uptr size = kMinFileLen; size <= max_len; size *= 2) { + fd_t fd = OpenFile(file_name, RdOnly, errno_p); + if (fd == kInvalidFd) return false; + UnmapOrDie(*buff, *buff_size); + *buff = (char*)MmapOrDie(size, __func__); + *buff_size = size; + *read_len = 0; + // Read up to one page at a time. + bool reached_eof = false; + while (*read_len + PageSize <= size) { + uptr just_read; + if (!ReadFromFile(fd, *buff + *read_len, PageSize, &just_read, errno_p)) { + UnmapOrDie(*buff, *buff_size); + return false; + } + if (just_read == 0) { + reached_eof = true; + break; + } + *read_len += just_read; + } + CloseFile(fd); + if (reached_eof) // We've read the whole file. + break; + } + return true; +} + +static const char kPathSeparator = SANITIZER_WINDOWS ? ';' : ':'; + +char *FindPathToBinary(const char *name) { + if (FileExists(name)) { + return internal_strdup(name); + } + + const char *path = GetEnv("PATH"); + if (!path) + return nullptr; + uptr name_len = internal_strlen(name); + InternalScopedBuffer buffer(kMaxPathLength); + const char *beg = path; + while (true) { + const char *end = internal_strchrnul(beg, kPathSeparator); + uptr prefix_len = end - beg; + if (prefix_len + name_len + 2 <= kMaxPathLength) { + internal_memcpy(buffer.data(), beg, prefix_len); + buffer[prefix_len] = '/'; + internal_memcpy(&buffer[prefix_len + 1], name, name_len); + buffer[prefix_len + 1 + name_len] = '\0'; + if (FileExists(buffer.data())) + return internal_strdup(buffer.data()); + } + if (*end == '\0') break; + beg = end + 1; + } + return nullptr; +} + +} // namespace __sanitizer + +using namespace __sanitizer; // NOLINT + +extern "C" { +void __sanitizer_set_report_path(const char *path) { + report_file.SetReportPath(path); +} + +void __sanitizer_set_report_fd(void *fd) { + report_file.fd = (fd_t)reinterpret_cast(fd); + report_file.fd_pid = internal_getpid(); +} +} // extern "C" Index: lib/sanitizer_common/sanitizer_linux_libcdep.cc =================================================================== --- lib/sanitizer_common/sanitizer_linux_libcdep.cc +++ lib/sanitizer_common/sanitizer_linux_libcdep.cc @@ -19,6 +19,7 @@ #include "sanitizer_allocator_internal.h" #include "sanitizer_atomic.h" #include "sanitizer_common.h" +#include "sanitizer_file.h" #include "sanitizer_flags.h" #include "sanitizer_freebsd.h" #include "sanitizer_linux.h" Index: lib/sanitizer_common/sanitizer_posix.cc =================================================================== --- lib/sanitizer_common/sanitizer_posix.cc +++ lib/sanitizer_common/sanitizer_posix.cc @@ -17,6 +17,7 @@ #if SANITIZER_POSIX #include "sanitizer_common.h" +#include "sanitizer_file.h" #include "sanitizer_libc.h" #include "sanitizer_posix.h" #include "sanitizer_procmaps.h" Index: lib/sanitizer_common/sanitizer_stacktrace_printer.cc =================================================================== --- lib/sanitizer_common/sanitizer_stacktrace_printer.cc +++ lib/sanitizer_common/sanitizer_stacktrace_printer.cc @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "sanitizer_stacktrace_printer.h" +#include "sanitizer_file.h" namespace __sanitizer { Index: lib/sanitizer_common/sanitizer_suppressions.cc =================================================================== --- lib/sanitizer_common/sanitizer_suppressions.cc +++ lib/sanitizer_common/sanitizer_suppressions.cc @@ -16,6 +16,7 @@ #include "sanitizer_allocator_internal.h" #include "sanitizer_common.h" #include "sanitizer_flags.h" +#include "sanitizer_file.h" #include "sanitizer_libc.h" #include "sanitizer_placement_new.h" Index: lib/sanitizer_common/sanitizer_symbolizer_internal.h =================================================================== --- lib/sanitizer_common/sanitizer_symbolizer_internal.h +++ lib/sanitizer_common/sanitizer_symbolizer_internal.h @@ -15,6 +15,7 @@ #define SANITIZER_SYMBOLIZER_INTERNAL_H #include "sanitizer_symbolizer.h" +#include "sanitizer_file.h" namespace __sanitizer { Index: lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc =================================================================== --- lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc +++ lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc @@ -16,6 +16,7 @@ #if SANITIZER_POSIX #include "sanitizer_allocator_internal.h" #include "sanitizer_common.h" +#include "sanitizer_file.h" #include "sanitizer_flags.h" #include "sanitizer_internal_defs.h" #include "sanitizer_linux.h" Index: lib/sanitizer_common/tests/sanitizer_common_test.cc =================================================================== --- lib/sanitizer_common/tests/sanitizer_common_test.cc +++ lib/sanitizer_common/tests/sanitizer_common_test.cc @@ -14,6 +14,7 @@ #include "sanitizer_common/sanitizer_allocator_internal.h" #include "sanitizer_common/sanitizer_common.h" +#include "sanitizer_common/sanitizer_file.h" #include "sanitizer_common/sanitizer_flags.h" #include "sanitizer_common/sanitizer_libc.h" #include "sanitizer_common/sanitizer_platform.h" Index: lib/sanitizer_common/tests/sanitizer_libc_test.cc =================================================================== --- lib/sanitizer_common/tests/sanitizer_libc_test.cc +++ lib/sanitizer_common/tests/sanitizer_libc_test.cc @@ -11,6 +11,7 @@ #include #include "sanitizer_common/sanitizer_common.h" +#include "sanitizer_common/sanitizer_file.h" #include "sanitizer_common/sanitizer_libc.h" #include "sanitizer_common/sanitizer_platform.h" #include "gtest/gtest.h" Index: lib/sanitizer_common/tests/sanitizer_linux_test.cc =================================================================== --- lib/sanitizer_common/tests/sanitizer_linux_test.cc +++ lib/sanitizer_common/tests/sanitizer_linux_test.cc @@ -17,6 +17,7 @@ #include "sanitizer_common/sanitizer_linux.h" #include "sanitizer_common/sanitizer_common.h" +#include "sanitizer_common/sanitizer_file.h" #include "gtest/gtest.h" #include Index: lib/stats/stats.cc =================================================================== --- lib/stats/stats.cc +++ lib/stats/stats.cc @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// #include "sanitizer_common/sanitizer_common.h" +#include "sanitizer_common/sanitizer_file.h" #include "sanitizer_common/sanitizer_internal_defs.h" #if SANITIZER_POSIX #include "sanitizer_common/sanitizer_posix.h" Index: lib/tsan/go/buildgo.sh =================================================================== --- lib/tsan/go/buildgo.sh +++ lib/tsan/go/buildgo.sh @@ -24,6 +24,7 @@ ../../sanitizer_common/sanitizer_common.cc ../../sanitizer_common/sanitizer_common_libcdep.cc ../../sanitizer_common/sanitizer_deadlock_detector2.cc + ../../sanitizer_common/sanitizer_file.cc ../../sanitizer_common/sanitizer_flag_parser.cc ../../sanitizer_common/sanitizer_flags.cc ../../sanitizer_common/sanitizer_libc.cc Index: lib/tsan/rtl/tsan_report.cc =================================================================== --- lib/tsan/rtl/tsan_report.cc +++ lib/tsan/rtl/tsan_report.cc @@ -13,6 +13,7 @@ #include "tsan_report.h" #include "tsan_platform.h" #include "tsan_rtl.h" +#include "sanitizer_common/sanitizer_file.h" #include "sanitizer_common/sanitizer_placement_new.h" #include "sanitizer_common/sanitizer_report_decorator.h" #include "sanitizer_common/sanitizer_stacktrace_printer.h" Index: lib/tsan/rtl/tsan_rtl.cc =================================================================== --- lib/tsan/rtl/tsan_rtl.cc +++ lib/tsan/rtl/tsan_rtl.cc @@ -14,6 +14,7 @@ #include "sanitizer_common/sanitizer_atomic.h" #include "sanitizer_common/sanitizer_common.h" +#include "sanitizer_common/sanitizer_file.h" #include "sanitizer_common/sanitizer_libc.h" #include "sanitizer_common/sanitizer_stackdepot.h" #include "sanitizer_common/sanitizer_placement_new.h"