[Sanitizers] Make OpenFile more portable
llvm-svn: 234410
This commit is contained in:
parent
ce6a4b82e7
commit
daa9e2d4e8
|
@ -58,14 +58,13 @@ void ReportFile::ReopenIfNecessary() {
|
|||
}
|
||||
|
||||
internal_snprintf(full_path, kMaxPathLength, "%s.%zu", path_prefix, pid);
|
||||
uptr openrv = OpenFile(full_path, WrOnly);
|
||||
if (internal_iserror(openrv)) {
|
||||
fd = OpenFile(full_path, WrOnly);
|
||||
if (fd == kInvalidFd) {
|
||||
const char *ErrorMsgPrefix = "ERROR: Can't open file: ";
|
||||
internal_write(kStderrFd, ErrorMsgPrefix, internal_strlen(ErrorMsgPrefix));
|
||||
internal_write(kStderrFd, full_path, internal_strlen(full_path));
|
||||
Die();
|
||||
}
|
||||
fd = openrv;
|
||||
fd_pid = pid;
|
||||
}
|
||||
|
||||
|
@ -136,7 +135,7 @@ void NORETURN CheckFailed(const char *file, int line, const char *cond,
|
|||
}
|
||||
|
||||
uptr ReadFileToBuffer(const char *file_name, char **buff, uptr *buff_size,
|
||||
uptr max_len, int *errno_p) {
|
||||
uptr max_len, error_t *errno_p) {
|
||||
uptr PageSize = GetPageSizeCached();
|
||||
uptr kMinFileLen = PageSize;
|
||||
uptr read_len = 0;
|
||||
|
@ -144,9 +143,8 @@ uptr ReadFileToBuffer(const char *file_name, char **buff, uptr *buff_size,
|
|||
*buff_size = 0;
|
||||
// The files we usually open are not seekable, so try different buffer sizes.
|
||||
for (uptr size = kMinFileLen; size <= max_len; size *= 2) {
|
||||
uptr openrv = OpenFile(file_name, RdOnly);
|
||||
if (internal_iserror(openrv, errno_p)) return 0;
|
||||
fd_t fd = openrv;
|
||||
fd_t fd = OpenFile(file_name, RdOnly, errno_p);
|
||||
if (fd == kInvalidFd) return 0;
|
||||
UnmapOrDie(*buff, *buff_size);
|
||||
*buff = (char*)MmapOrDie(size, __func__);
|
||||
*buff_size = size;
|
||||
|
|
|
@ -196,18 +196,20 @@ enum FileAccessMode {
|
|||
RdWr
|
||||
};
|
||||
|
||||
uptr OpenFile(const char *filename, FileAccessMode mode);
|
||||
// Returns kInvalidFd on error.
|
||||
fd_t OpenFile(const char *filename, FileAccessMode mode,
|
||||
error_t *errno_p = nullptr);
|
||||
// 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',
|
||||
// Returns the number of read bytes or 0 if file can not be opened.
|
||||
uptr ReadFileToBuffer(const char *file_name, char **buff, uptr *buff_size,
|
||||
uptr max_len, int *errno_p = nullptr);
|
||||
uptr max_len, error_t *errno_p = nullptr);
|
||||
// Maps given file to virtual memory, and returns pointer to it
|
||||
// (or NULL if the mapping failes). Stores the size of mmaped region
|
||||
// (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, uptr fd, uptr offset);
|
||||
void *MapWritableFileToMemory(void *addr, uptr size, fd_t fd, uptr offset);
|
||||
|
||||
bool IsAccessibleMemoryRange(uptr beg, uptr size);
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@ static atomic_uintptr_t coverage_counter;
|
|||
// dump current memory layout to another file.
|
||||
|
||||
static bool cov_sandboxed = false;
|
||||
static int cov_fd = kInvalidFd;
|
||||
static fd_t cov_fd = kInvalidFd;
|
||||
static unsigned int cov_max_block_size = 0;
|
||||
static bool coverage_enabled = false;
|
||||
static const char *coverage_dir;
|
||||
|
@ -124,7 +124,7 @@ class CoverageData {
|
|||
// Current file mapped size of the pc array.
|
||||
uptr pc_array_mapped_size;
|
||||
// Descriptor of the file mapped pc array.
|
||||
int pc_fd;
|
||||
fd_t pc_fd;
|
||||
|
||||
// Vector of coverage guard arrays, protected by mu.
|
||||
InternalMmapVectorNoCtor<s32*> guard_array_vec;
|
||||
|
@ -177,7 +177,7 @@ void CoverageData::DirectOpen() {
|
|||
internal_snprintf((char *)path.data(), path.size(), "%s/%zd.sancov.raw",
|
||||
coverage_dir, internal_getpid());
|
||||
pc_fd = OpenFile(path.data(), RdWr);
|
||||
if (internal_iserror(pc_fd)) {
|
||||
if (pc_fd == kInvalidFd) {
|
||||
Report("Coverage: failed to open %s for reading/writing\n", path.data());
|
||||
Die();
|
||||
}
|
||||
|
@ -516,7 +516,7 @@ struct CovHeader {
|
|||
|
||||
static void CovWritePacked(int pid, const char *module, const void *blob,
|
||||
unsigned int blob_size) {
|
||||
if (cov_fd < 0) return;
|
||||
if (cov_fd == kInvalidFd) return;
|
||||
unsigned module_name_length = internal_strlen(module);
|
||||
CovHeader header = {pid, module_name_length, blob_size};
|
||||
|
||||
|
@ -557,7 +557,7 @@ static void CovWritePacked(int pid, const char *module, const void *blob,
|
|||
// If packed = true and name == 0: <pid>.<sancov>.<packed>.
|
||||
// If packed = true and name != 0: <name>.<sancov>.<packed> (name is
|
||||
// user-supplied).
|
||||
static int CovOpenFile(InternalScopedString *path, bool packed,
|
||||
static fd_t CovOpenFile(InternalScopedString *path, bool packed,
|
||||
const char *name, const char *extension = "sancov") {
|
||||
path->clear();
|
||||
if (!packed) {
|
||||
|
@ -571,11 +571,9 @@ static int CovOpenFile(InternalScopedString *path, bool packed,
|
|||
else
|
||||
path->append("%s/%s.%s.packed", coverage_dir, name, extension);
|
||||
}
|
||||
uptr fd = OpenFile(path->data(), WrOnly);
|
||||
if (internal_iserror(fd)) {
|
||||
fd_t fd = OpenFile(path->data(), WrOnly);
|
||||
if (fd == kInvalidFd)
|
||||
Report("SanitizerCoverage: failed to open %s for writing\n", path->data());
|
||||
return -1;
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
|
@ -595,13 +593,13 @@ void CoverageData::DumpTrace() {
|
|||
out.append("%s 0x%zx\n", module_name, module_address);
|
||||
}
|
||||
InternalScopedString path(kMaxPathLength);
|
||||
int fd = CovOpenFile(&path, false, "trace-points");
|
||||
if (fd < 0) return;
|
||||
fd_t fd = CovOpenFile(&path, false, "trace-points");
|
||||
if (fd == kInvalidFd) return;
|
||||
internal_write(fd, out.data(), out.length());
|
||||
internal_close(fd);
|
||||
|
||||
fd = CovOpenFile(&path, false, "trace-compunits");
|
||||
if (fd < 0) return;
|
||||
if (fd == kInvalidFd) return;
|
||||
out.clear();
|
||||
for (uptr i = 0; i < comp_unit_name_vec.size(); i++)
|
||||
out.append("%s\n", comp_unit_name_vec[i].copied_module_name);
|
||||
|
@ -609,7 +607,7 @@ void CoverageData::DumpTrace() {
|
|||
internal_close(fd);
|
||||
|
||||
fd = CovOpenFile(&path, false, "trace-events");
|
||||
if (fd < 0) return;
|
||||
if (fd == kInvalidFd) return;
|
||||
uptr bytes_to_write = max_idx * sizeof(tr_event_array[0]);
|
||||
u8 *event_bytes = reinterpret_cast<u8*>(tr_event_array);
|
||||
// The trace file could be huge, and may not be written with a single syscall.
|
||||
|
@ -660,8 +658,8 @@ void CoverageData::DumpCallerCalleePairs() {
|
|||
}
|
||||
}
|
||||
InternalScopedString path(kMaxPathLength);
|
||||
int fd = CovOpenFile(&path, false, "caller-callee");
|
||||
if (fd < 0) return;
|
||||
fd_t fd = CovOpenFile(&path, false, "caller-callee");
|
||||
if (fd == kInvalidFd) return;
|
||||
internal_write(fd, out.data(), out.length());
|
||||
internal_close(fd);
|
||||
VReport(1, " CovDump: %zd caller-callee pairs written\n", total);
|
||||
|
@ -694,9 +692,9 @@ void CoverageData::DumpCounters() {
|
|||
CHECK_LE(r.beg, r.end);
|
||||
CHECK_LE(r.end, size());
|
||||
const char *base_name = StripModuleName(r.copied_module_name);
|
||||
int fd =
|
||||
fd_t fd =
|
||||
CovOpenFile(&path, /* packed */ false, base_name, "counters-sancov");
|
||||
if (fd < 0) return;
|
||||
if (fd == kInvalidFd) return;
|
||||
internal_write(fd, bitset.data() + r.beg, r.end - r.beg);
|
||||
internal_close(fd);
|
||||
VReport(1, " CovDump: %zd counters written for '%s'\n", r.end - r.beg,
|
||||
|
@ -722,8 +720,8 @@ void CoverageData::DumpAsBitSet() {
|
|||
n_set_bits++;
|
||||
}
|
||||
const char *base_name = StripModuleName(r.copied_module_name);
|
||||
int fd = CovOpenFile(&path, /* packed */ false, base_name, "bitset-sancov");
|
||||
if (fd < 0) return;
|
||||
fd_t fd = CovOpenFile(&path, /* packed */false, base_name, "bitset-sancov");
|
||||
if (fd == kInvalidFd) return;
|
||||
internal_write(fd, out.data() + r.beg, r.end - r.beg);
|
||||
internal_close(fd);
|
||||
VReport(1,
|
||||
|
@ -770,21 +768,21 @@ void CoverageData::DumpOffsets() {
|
|||
|
||||
const char *module_name = StripModuleName(r.copied_module_name);
|
||||
if (cov_sandboxed) {
|
||||
if (cov_fd >= 0) {
|
||||
if (cov_fd != kInvalidFd) {
|
||||
CovWritePacked(internal_getpid(), module_name, offsets.data(),
|
||||
offsets.size() * sizeof(offsets[0]));
|
||||
VReport(1, " CovDump: %zd PCs written to packed file\n", num_offsets);
|
||||
}
|
||||
} else {
|
||||
// One file per module per process.
|
||||
int fd = CovOpenFile(&path, false /* packed */, module_name);
|
||||
if (fd < 0) continue;
|
||||
fd_t fd = CovOpenFile(&path, false /* packed */, module_name);
|
||||
if (fd == kInvalidFd) continue;
|
||||
internal_write(fd, offsets.data(), offsets.size() * sizeof(offsets[0]));
|
||||
internal_close(fd);
|
||||
VReport(1, " CovDump: %s: %zd PCs written\n", path.data(), num_offsets);
|
||||
}
|
||||
}
|
||||
if (cov_fd >= 0)
|
||||
if (cov_fd != kInvalidFd)
|
||||
internal_close(cov_fd);
|
||||
}
|
||||
|
||||
|
@ -804,16 +802,17 @@ void CovPrepareForSandboxing(__sanitizer_sandbox_arguments *args) {
|
|||
if (!coverage_enabled) return;
|
||||
cov_sandboxed = args->coverage_sandboxed;
|
||||
if (!cov_sandboxed) return;
|
||||
cov_fd = args->coverage_fd;
|
||||
cov_max_block_size = args->coverage_max_block_size;
|
||||
if (cov_fd < 0) {
|
||||
if (args->coverage_fd >= 0) {
|
||||
cov_fd = args->coverage_fd;
|
||||
} else {
|
||||
InternalScopedString path(kMaxPathLength);
|
||||
// Pre-open the file now. The sandbox won't allow us to do it later.
|
||||
cov_fd = CovOpenFile(&path, true /* packed */, 0);
|
||||
}
|
||||
}
|
||||
|
||||
int MaybeOpenCovFile(const char *name) {
|
||||
fd_t MaybeOpenCovFile(const char *name) {
|
||||
CHECK(name);
|
||||
if (!coverage_enabled) return -1;
|
||||
InternalScopedString path(kMaxPathLength);
|
||||
|
@ -890,7 +889,7 @@ __sanitizer_cov_module_init(s32 *guards, uptr npcs, u8 *counters,
|
|||
}
|
||||
SANITIZER_INTERFACE_ATTRIBUTE
|
||||
sptr __sanitizer_maybe_open_cov_file(const char *name) {
|
||||
return MaybeOpenCovFile(name);
|
||||
return (sptr)MaybeOpenCovFile(name);
|
||||
}
|
||||
SANITIZER_INTERFACE_ATTRIBUTE
|
||||
uptr __sanitizer_get_total_unique_coverage() {
|
||||
|
|
|
@ -101,8 +101,8 @@ void CovUpdateMapping(const char *coverage_dir, uptr caller_pc) {
|
|||
"%s/%zd.sancov.map.tmp", coverage_dir,
|
||||
internal_getpid());
|
||||
CHECK_LE(res, tmp_path.size());
|
||||
uptr map_fd = OpenFile(tmp_path.data(), WrOnly);
|
||||
if (internal_iserror(map_fd, &err)) {
|
||||
fd_t map_fd = OpenFile(tmp_path.data(), WrOnly, &err);
|
||||
if (map_fd == kInvalidFd) {
|
||||
Report("Coverage: failed to open %s for writing: %d\n", tmp_path.data(),
|
||||
err);
|
||||
Die();
|
||||
|
|
|
@ -81,6 +81,7 @@ typedef signed short s16; // NOLINT
|
|||
typedef signed int s32;
|
||||
typedef signed long long s64; // NOLINT
|
||||
typedef int fd_t;
|
||||
typedef int error_t;
|
||||
|
||||
// WARNING: OFF_T may be different from OS type off_t, depending on the value of
|
||||
// _FILE_OFFSET_BITS. This definition of OFF_T matches the ABI of system calls
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
// run-time libraries.
|
||||
// These tools can not use some of the libc functions directly because those
|
||||
// functions are intercepted. Instead, we implement a tiny subset of libc here.
|
||||
// FIXME: Some of functions declared in this file are in fact POSIX, not libc.
|
||||
//===----------------------------------------------------------------------===//
|
||||
#ifndef SANITIZER_LIBC_H
|
||||
#define SANITIZER_LIBC_H
|
||||
|
|
|
@ -473,8 +473,8 @@ static uptr GetRSSFromGetrusage() {
|
|||
uptr GetRSS() {
|
||||
if (!common_flags()->can_use_proc_maps_statm)
|
||||
return GetRSSFromGetrusage();
|
||||
uptr fd = OpenFile("/proc/self/statm", RdOnly);
|
||||
if ((sptr)fd < 0)
|
||||
fd_t fd = OpenFile("/proc/self/statm", RdOnly);
|
||||
if (fd == kInvalidFd)
|
||||
return GetRSSFromGetrusage();
|
||||
char buf[64];
|
||||
uptr len = internal_read(fd, buf, sizeof(buf) - 1);
|
||||
|
|
|
@ -205,20 +205,22 @@ void *Mprotect(uptr fixed_addr, uptr size) {
|
|||
MAP_NORESERVE, -1, 0);
|
||||
}
|
||||
|
||||
uptr OpenFile(const char *filename, FileAccessMode mode) {
|
||||
fd_t OpenFile(const char *filename, FileAccessMode mode, error_t *errno_p) {
|
||||
int flags;
|
||||
switch (mode) {
|
||||
case RdOnly: flags = O_RDONLY; break;
|
||||
case WrOnly: flags = O_WRONLY | O_CREAT; break;
|
||||
case RdWr: flags = O_RDWR | O_CREAT; break;
|
||||
}
|
||||
return internal_open(filename, flags, 0660);
|
||||
fd_t res = internal_open(filename, flags, 0660);
|
||||
if (internal_iserror(res, errno_p))
|
||||
return kInvalidFd;
|
||||
return res;
|
||||
}
|
||||
|
||||
void *MapFileToMemory(const char *file_name, uptr *buff_size) {
|
||||
uptr openrv = OpenFile(file_name, RdOnly);
|
||||
CHECK(!internal_iserror(openrv));
|
||||
fd_t fd = openrv;
|
||||
fd_t fd = OpenFile(file_name, RdOnly);
|
||||
CHECK(fd != kInvalidFd);
|
||||
uptr fsize = internal_filesize(fd);
|
||||
CHECK_NE(fsize, (uptr)-1);
|
||||
CHECK_GT(fsize, 0);
|
||||
|
@ -227,13 +229,13 @@ void *MapFileToMemory(const char *file_name, uptr *buff_size) {
|
|||
return internal_iserror(map) ? 0 : (void *)map;
|
||||
}
|
||||
|
||||
void *MapWritableFileToMemory(void *addr, uptr size, uptr fd, uptr offset) {
|
||||
void *MapWritableFileToMemory(void *addr, uptr size, fd_t fd, uptr offset) {
|
||||
uptr flags = MAP_SHARED;
|
||||
if (addr) flags |= MAP_FIXED;
|
||||
uptr p = internal_mmap(addr, size, PROT_READ | PROT_WRITE, flags, fd, offset);
|
||||
int mmap_errno = 0;
|
||||
if (internal_iserror(p, &mmap_errno)) {
|
||||
Printf("could not map writable file (%zd, %zu, %zu): %zd, errno: %d\n",
|
||||
Printf("could not map writable file (%d, %zu, %zu): %zd, errno: %d\n",
|
||||
fd, offset, size, p, mmap_errno);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -160,7 +160,7 @@ void *MapFileToMemory(const char *file_name, uptr *buff_size) {
|
|||
UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
void *MapWritableFileToMemory(void *addr, uptr size, uptr fd, uptr offset) {
|
||||
void *MapWritableFileToMemory(void *addr, uptr size, fd_t fd, uptr offset) {
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
|
@ -420,7 +420,7 @@ uptr internal_open(const char *filename, int flags, u32 mode) {
|
|||
UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
uptr OpenFile(const char *filename, FileAccessMode mode) {
|
||||
fd_t OpenFile(const char *filename, FileAccessMode mode, error_t *last_error) {
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
|
|
|
@ -78,16 +78,14 @@ TEST(SanitizerCommon, FileOps) {
|
|||
|
||||
char tmpfile[128];
|
||||
temp_file_name(tmpfile, sizeof(tmpfile), "sanitizer_common.fileops.tmp.");
|
||||
uptr openrv = OpenFile(tmpfile, WrOnly);
|
||||
EXPECT_FALSE(internal_iserror(openrv));
|
||||
fd_t fd = openrv;
|
||||
fd_t fd = OpenFile(tmpfile, WrOnly);
|
||||
ASSERT_NE(fd, kInvalidFd);
|
||||
EXPECT_EQ(len1, internal_write(fd, str1, len1));
|
||||
EXPECT_EQ(len2, internal_write(fd, str2, len2));
|
||||
internal_close(fd);
|
||||
|
||||
openrv = OpenFile(tmpfile, RdOnly);
|
||||
EXPECT_FALSE(internal_iserror(openrv));
|
||||
fd = openrv;
|
||||
fd = OpenFile(tmpfile, RdOnly);
|
||||
ASSERT_NE(fd, kInvalidFd);
|
||||
uptr fsize = internal_filesize(fd);
|
||||
EXPECT_EQ(len1 + len2, fsize);
|
||||
|
||||
|
@ -134,12 +132,11 @@ TEST(SanitizerCommon, InternalMmapWithOffset) {
|
|||
char tmpfile[128];
|
||||
temp_file_name(tmpfile, sizeof(tmpfile),
|
||||
"sanitizer_common.internalmmapwithoffset.tmp.");
|
||||
uptr res = OpenFile(tmpfile, RdWr);
|
||||
ASSERT_FALSE(internal_iserror(res));
|
||||
fd_t fd = res;
|
||||
fd_t fd = OpenFile(tmpfile, RdWr);
|
||||
ASSERT_NE(fd, kInvalidFd);
|
||||
|
||||
uptr page_size = GetPageSizeCached();
|
||||
res = internal_ftruncate(fd, page_size * 2);
|
||||
uptr res = internal_ftruncate(fd, page_size * 2);
|
||||
ASSERT_FALSE(internal_iserror(res));
|
||||
|
||||
res = internal_lseek(fd, page_size, SEEK_SET);
|
||||
|
|
|
@ -153,12 +153,12 @@ static void BackgroundThread(void *arg) {
|
|||
} else {
|
||||
InternalScopedString filename(kMaxPathLength);
|
||||
filename.append("%s.%d", flags()->profile_memory, (int)internal_getpid());
|
||||
uptr openrv = OpenFile(filename.data(), WrOnly);
|
||||
if (internal_iserror(openrv)) {
|
||||
fd_t fd = OpenFile(filename.data(), WrOnly);
|
||||
if (fd == kInvalidFd) {
|
||||
Printf("ThreadSanitizer: failed to open memory profile file '%s'\n",
|
||||
&filename[0]);
|
||||
} else {
|
||||
mprof_fd = openrv;
|
||||
mprof_fd = fd;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue