[compiler-rt] r242594 - [Sanitizer] Teach ReadFileToBuffer to distinguish empty file from inaccessible file.
Alexey Samsonov
vonosmas at gmail.com
Fri Jul 17 16:50:08 PDT 2015
Author: samsonov
Date: Fri Jul 17 18:50:08 2015
New Revision: 242594
URL: http://llvm.org/viewvc/llvm-project?rev=242594&view=rev
Log:
[Sanitizer] Teach ReadFileToBuffer to distinguish empty file from inaccessible file.
Summary:
This fixes https://code.google.com/p/address-sanitizer/issues/detail?id=399
(sanitizers crash with empty suppression files).
Reviewers: kcc
Subscribers: llvm-commits
Differential Revision: http://reviews.llvm.org/D11284
Modified:
compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.cc
compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h
compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.cc
compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc
compiler-rt/trunk/lib/sanitizer_common/sanitizer_procmaps_common.cc
compiler-rt/trunk/lib/sanitizer_common/sanitizer_procmaps_linux.cc
compiler-rt/trunk/lib/sanitizer_common/sanitizer_suppressions.cc
compiler-rt/trunk/test/lsan/TestCases/suppressions_file.cc
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.cc?rev=242594&r1=242593&r2=242594&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.cc Fri Jul 17 18:50:08 2015
@@ -140,40 +140,40 @@ void NORETURN CheckFailed(const char *fi
Die();
}
-uptr ReadFileToBuffer(const char *file_name, char **buff, uptr *buff_size,
- uptr max_len, error_t *errno_p) {
+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;
- uptr read_len = 0;
- *buff = 0;
+ *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 0;
+ 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.
- read_len = 0;
bool reached_eof = false;
- while (read_len + PageSize <= size) {
+ while (*read_len + PageSize <= size) {
uptr just_read;
- if (!ReadFromFile(fd, *buff + read_len, PageSize, &just_read, errno_p)) {
+ if (!ReadFromFile(fd, *buff + *read_len, PageSize, &just_read, errno_p)) {
UnmapOrDie(*buff, *buff_size);
- return 0;
+ return false;
}
if (just_read == 0) {
reached_eof = true;
break;
}
- read_len += just_read;
+ *read_len += just_read;
}
CloseFile(fd);
if (reached_eof) // We've read the whole file.
break;
}
- return read_len;
+ return true;
}
typedef bool UptrComparisonFunction(const uptr &a, const uptr &b);
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h?rev=242594&r1=242593&r2=242594&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h Fri Jul 17 18:50:08 2015
@@ -228,10 +228,12 @@ 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',
-// 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, error_t *errno_p = nullptr);
+// The size of the mmaped region is stored in '*buff_size'.
+// The total number of read bytes is stored in '*read_len'.
+// Returns true if file was successfully opened and read.
+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'.
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.cc?rev=242594&r1=242593&r2=242594&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.cc Fri Jul 17 18:50:08 2015
@@ -54,11 +54,10 @@ class FlagHandlerInclude : public FlagHa
bool Parse(const char *value) final {
char *data;
uptr data_mapped_size;
+ uptr len;
error_t err;
- uptr len =
- ReadFileToBuffer(value, &data, &data_mapped_size,
- Max(kMaxIncludeSize, GetPageSizeCached()), &err);
- if (!len) {
+ if (!ReadFileToBuffer(value, &data, &data_mapped_size, &len,
+ Max(kMaxIncludeSize, GetPageSizeCached()), &err)) {
Printf("Failed to read options from '%s': error %d\n", value, err);
return false;
}
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc?rev=242594&r1=242593&r2=242594&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc Fri Jul 17 18:50:08 2015
@@ -375,8 +375,8 @@ const char *GetEnv(const char *name) {
if (!inited) {
inited = true;
uptr environ_size;
- len = ReadFileToBuffer("/proc/self/environ",
- &environ, &environ_size, 1 << 26);
+ if (!ReadFileToBuffer("/proc/self/environ", &environ, &environ_size, &len))
+ environ = nullptr;
}
if (!environ || len == 0) return 0;
uptr namelen = internal_strlen(name);
@@ -405,9 +405,13 @@ extern "C" {
static void ReadNullSepFileToArray(const char *path, char ***arr,
int arr_size) {
char *buff;
- uptr buff_size = 0;
+ uptr buff_size;
+ uptr buff_len;
*arr = (char **)MmapOrDie(arr_size * sizeof(char *), "NullSepFileArray");
- ReadFileToBuffer(path, &buff, &buff_size, 1024 * 1024);
+ if (!ReadFileToBuffer(path, &buff, &buff_size, &buff_len, 1024 * 1024)) {
+ (*arr)[0] = nullptr;
+ return;
+ }
(*arr)[0] = buff;
int count, i;
for (count = 1, i = 1; ; i++) {
@@ -418,7 +422,7 @@ static void ReadNullSepFileToArray(const
count++;
}
}
- (*arr)[count] = 0;
+ (*arr)[count] = nullptr;
}
#endif
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_procmaps_common.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_procmaps_common.cc?rev=242594&r1=242593&r2=242594&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_procmaps_common.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_procmaps_common.cc Fri Jul 17 18:50:08 2015
@@ -153,8 +153,9 @@ uptr MemoryMappingLayout::DumpListOfModu
void GetMemoryProfile(fill_profile_f cb, uptr *stats, uptr stats_size) {
char *smaps = 0;
uptr smaps_cap = 0;
- uptr smaps_len = ReadFileToBuffer("/proc/self/smaps",
- &smaps, &smaps_cap, 64<<20);
+ uptr smaps_len = 0;
+ if (!ReadFileToBuffer("/proc/self/smaps", &smaps, &smaps_cap, &smaps_len))
+ return;
uptr start = 0;
bool file = false;
const char *pos = smaps;
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_procmaps_linux.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_procmaps_linux.cc?rev=242594&r1=242593&r2=242594&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_procmaps_linux.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_procmaps_linux.cc Fri Jul 17 18:50:08 2015
@@ -18,8 +18,8 @@
namespace __sanitizer {
void ReadProcMaps(ProcSelfMapsBuff *proc_maps) {
- proc_maps->len = ReadFileToBuffer("/proc/self/maps", &proc_maps->data,
- &proc_maps->mmaped_size, 1 << 26);
+ CHECK(ReadFileToBuffer("/proc/self/maps", &proc_maps->data,
+ &proc_maps->mmaped_size, &proc_maps->len));
}
static bool IsOneOf(char c, char c1, char c2) {
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_suppressions.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_suppressions.cc?rev=242594&r1=242593&r2=242594&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_suppressions.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_suppressions.cc Fri Jul 17 18:50:08 2015
@@ -60,15 +60,13 @@ void SuppressionContext::ParseFromFile(c
}
// Read the file.
- char *file_contents;
- uptr buffer_size;
- const uptr max_len = 1 << 26;
- uptr contents_size =
- ReadFileToBuffer(filename, &file_contents, &buffer_size, max_len);
VPrintf(1, "%s: reading suppressions file at %s\n",
SanitizerToolName, filename);
-
- if (contents_size == 0) {
+ char *file_contents;
+ uptr buffer_size;
+ uptr contents_size;
+ if (!ReadFileToBuffer(filename, &file_contents, &buffer_size,
+ &contents_size)) {
Printf("%s: failed to read suppressions file '%s'\n", SanitizerToolName,
filename);
Die();
Modified: compiler-rt/trunk/test/lsan/TestCases/suppressions_file.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/lsan/TestCases/suppressions_file.cc?rev=242594&r1=242593&r2=242594&view=diff
==============================================================================
--- compiler-rt/trunk/test/lsan/TestCases/suppressions_file.cc (original)
+++ compiler-rt/trunk/test/lsan/TestCases/suppressions_file.cc Fri Jul 17 18:50:08 2015
@@ -1,6 +1,10 @@
// RUN: LSAN_BASE="use_registers=0:use_stacks=0"
// RUN: %clangxx_lsan %s -o %t
+// RUN: rm -f %t.supp
+// RUN: touch %t.supp
+// RUN: LSAN_OPTIONS="$LSAN_BASE:suppressions='%t.supp'" not %run %t 2>&1 | FileCheck %s --check-prefix=NOSUPP
+
// RUN: echo "leak:*LSanTestLeakingFunc*" > %t.supp
// RUN: LSAN_OPTIONS="$LSAN_BASE:suppressions='%t.supp'" not %run %t 2>&1 | FileCheck %s
@@ -24,3 +28,5 @@ int main() {
// CHECK: Suppressions used:
// CHECK: 1 666 *LSanTestLeakingFunc*
// CHECK: SUMMARY: {{(Leak|Address)}}Sanitizer: 1337 byte(s) leaked in 1 allocation(s)
+
+// NOSUPP: SUMMARY: {{(Leak|Address)}}Sanitizer: 2003 byte(s) leaked in 2 allocation(s).
More information about the llvm-commits
mailing list