forked from OSchip/llvm-project
[sanitizer_common] Move filesystem-related code out of sanitizer_common.cc
Summary: This is a pure refactoring change. It just moves code that is related to filesystem operations from sanitizer_common.{cc,h} to sanitizer_file.{cc,h}. This makes it cleaner to disable the filesystem-related code for a new port that doesn't want it. Submitted on behalf of Roland McGrath. Reviewers: kcc, eugenis, alekseyshl Reviewed By: alekseyshl Subscribers: vitalybuka, llvm-commits, kubamracek, mgorny, phosek Tags: #sanitizers Differential Revision: https://reviews.llvm.org/D35591 llvm-svn: 308819
This commit is contained in:
parent
abfe380f9a
commit
d4abe9e7d3
|
@ -141,9 +141,9 @@ class ScopedInErrorReport {
|
|||
|
||||
// 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);
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -7,6 +7,7 @@ set(SANITIZER_SOURCES_NOTERMINATION
|
|||
sanitizer_deadlock_detector1.cc
|
||||
sanitizer_deadlock_detector2.cc
|
||||
sanitizer_errno.cc
|
||||
sanitizer_file.cc
|
||||
sanitizer_flags.cc
|
||||
sanitizer_flag_parser.cc
|
||||
sanitizer_libc.cc
|
||||
|
@ -96,6 +97,7 @@ set(SANITIZER_HEADERS
|
|||
sanitizer_deadlock_detector_interface.h
|
||||
sanitizer_errno.h
|
||||
sanitizer_errno_codes.h
|
||||
sanitizer_file.h
|
||||
sanitizer_flag_parser.h
|
||||
sanitizer_flags.h
|
||||
sanitizer_flags.inc
|
||||
|
|
|
@ -27,72 +27,6 @@ const char *SanitizerToolName = "SanitizerTool";
|
|||
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 @@ void NORETURN ReportMmapFailureAndDie(uptr size, const char *mem_type,
|
|||
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);
|
||||
|
||||
|
@ -359,36 +257,6 @@ bool TemplateMatch(const char *templ, const char *str) {
|
|||
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<char> 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];
|
||||
|
||||
|
@ -482,15 +350,6 @@ static int InstallMallocFreeHooks(void (*malloc_hook)(const void *, uptr),
|
|||
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<uptr>(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);
|
||||
|
|
|
@ -185,6 +185,7 @@ typedef void (*LowLevelAllocateCallback)(uptr ptr, uptr size);
|
|||
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 @@ void SetPrintfAndReportCallback(void (*callback)(const char *));
|
|||
// 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 <path_prefix>.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 SupportsColoredOutput(fd_t fd);
|
|||
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 CacheBinaryName();
|
|||
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();
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -0,0 +1,171 @@
|
|||
//===-- 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. It defines filesystem-related interfaces. This
|
||||
// is separate from sanitizer_common.cc so that it's simpler to disable
|
||||
// all the filesystem support code for a port that doesn't use it.
|
||||
//
|
||||
//===---------------------------------------------------------------------===//
|
||||
|
||||
#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<char> 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<uptr>(fd);
|
||||
report_file.fd_pid = internal_getpid();
|
||||
}
|
||||
} // extern "C"
|
|
@ -0,0 +1,110 @@
|
|||
//===-- 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.
|
||||
// It declares filesystem-related interfaces. This is separate from
|
||||
// sanitizer_common.h so that it's simpler to disable all the filesystem
|
||||
// support code for a port that doesn't use it.
|
||||
//
|
||||
//===---------------------------------------------------------------------===//
|
||||
#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 <path_prefix>.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
|
|
@ -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"
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include "sanitizer_common.h"
|
||||
#include "sanitizer_file.h"
|
||||
#include "sanitizer_flags.h"
|
||||
#include "sanitizer_internal_defs.h"
|
||||
#include "sanitizer_libc.h"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "sanitizer_stacktrace_printer.h"
|
||||
#include "sanitizer_file.h"
|
||||
|
||||
namespace __sanitizer {
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#define SANITIZER_SYMBOLIZER_INTERNAL_H
|
||||
|
||||
#include "sanitizer_symbolizer.h"
|
||||
#include "sanitizer_file.h"
|
||||
|
||||
namespace __sanitizer {
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include "sanitizer_common.h"
|
||||
#include "sanitizer_dbghelp.h"
|
||||
#include "sanitizer_file.h"
|
||||
#include "sanitizer_libc.h"
|
||||
#include "sanitizer_mutex.h"
|
||||
#include "sanitizer_placement_new.h"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <algorithm>
|
||||
|
||||
#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"
|
||||
|
|
|
@ -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 <pthread.h>
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -24,6 +24,7 @@ SRCS="
|
|||
../../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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue