summaryrefslogtreecommitdiffstats
path: root/libsanitizer/sanitizer_common
diff options
context:
space:
mode:
authorkcc <kcc@138bc75d-0d04-0410-961f-82ee72b054a4>2012-11-23 14:46:25 +0000
committerkcc <kcc@138bc75d-0d04-0410-961f-82ee72b054a4>2012-11-23 14:46:25 +0000
commit0d996a11d9b5be7a52d77016de51910146ceaa90 (patch)
treea354102cd1c27b09eefe0b04f517d4ecac5bc566 /libsanitizer/sanitizer_common
parenta46419387192ae39f45cfeca2ec0afe6f872956e (diff)
downloadppe42-gcc-0d996a11d9b5be7a52d77016de51910146ceaa90.tar.gz
ppe42-gcc-0d996a11d9b5be7a52d77016de51910146ceaa90.zip
[libsanitizer] merge from upstream r168514
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@193756 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libsanitizer/sanitizer_common')
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_allocator64.h9
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_common.cc50
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_common.h22
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_internal_defs.h47
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_libc.cc17
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_libc.h5
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_linux.cc18
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_mac.cc8
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_placement_new.h2
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_posix.cc17
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_printf.cc57
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_procmaps.h1
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_stacktrace.cc24
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_stacktrace.h2
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_symbolizer.cc3
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_symbolizer.h2
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_symbolizer_linux.cc20
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_symbolizer_mac.cc2
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_symbolizer_win.cc2
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_win.cc37
20 files changed, 245 insertions, 100 deletions
diff --git a/libsanitizer/sanitizer_common/sanitizer_allocator64.h b/libsanitizer/sanitizer_common/sanitizer_allocator64.h
index 247719876aa..7614aba52ac 100644
--- a/libsanitizer/sanitizer_common/sanitizer_allocator64.h
+++ b/libsanitizer/sanitizer_common/sanitizer_allocator64.h
@@ -16,7 +16,7 @@
#define SANITIZER_ALLOCATOR_H
#include "sanitizer_internal_defs.h"
-#if __WORDSIZE != 64
+#if SANITIZER_WORDSIZE != 64
# error "sanitizer_allocator64.h can only be used on 64-bit platforms"
#endif
@@ -275,7 +275,12 @@ class SizeClassAllocator64 {
} while (idx < end_idx);
region->allocated_user += idx - beg_idx;
region->allocated_meta += i * kMetadataSize;
- CHECK_LT(region->allocated_user + region->allocated_meta, kRegionSize);
+ if (region->allocated_user + region->allocated_meta > kRegionSize) {
+ Printf("Out of memory. Dying.\n");
+ Printf("The process has exhausted %zuMB for size class %zu.\n",
+ kRegionSize / 1024 / 1024, size);
+ Die();
+ }
}
void *AllocateBySizeClass(uptr class_id) {
diff --git a/libsanitizer/sanitizer_common/sanitizer_common.cc b/libsanitizer/sanitizer_common/sanitizer_common.cc
index 43ef980e846..fda67a542d5 100644
--- a/libsanitizer/sanitizer_common/sanitizer_common.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_common.cc
@@ -14,7 +14,9 @@
namespace __sanitizer {
-static fd_t report_fd = 2; // By default, dump to stderr.
+// By default, dump to stderr. If report_fd is kInvalidFd, try to obtain file
+// descriptor by opening file in report_path.
+static fd_t report_fd = kStderrFd;
static char report_path[4096]; // Set via __sanitizer_set_report_path.
static void (*DieCallback)(void);
@@ -44,18 +46,27 @@ void NORETURN CheckFailed(const char *file, int line, const char *cond,
Die();
}
+static void MaybeOpenReportFile() {
+ if (report_fd != kInvalidFd)
+ return;
+ fd_t fd = internal_open(report_path, true);
+ if (fd == kInvalidFd) {
+ report_fd = kStderrFd;
+ Report("ERROR: Can't open file: %s\n", report_path);
+ Die();
+ }
+ report_fd = fd;
+}
+
+bool PrintsToTty() {
+ MaybeOpenReportFile();
+ return internal_isatty(report_fd);
+}
+
void RawWrite(const char *buffer) {
static const char *kRawWriteError = "RawWrite can't output requested buffer!";
uptr length = (uptr)internal_strlen(buffer);
- if (report_fd == kInvalidFd) {
- fd_t fd = internal_open(report_path, true);
- if (fd == kInvalidFd) {
- report_fd = 2;
- Report("ERROR: Can't open file: %s\n", report_path);
- Die();
- }
- report_fd = fd;
- }
+ MaybeOpenReportFile();
if (length != internal_write(report_fd, buffer, length)) {
internal_write(report_fd, kRawWriteError, internal_strlen(kRawWriteError));
Die();
@@ -136,16 +147,27 @@ void SortArray(uptr *array, uptr size) {
} // namespace __sanitizer
+using namespace __sanitizer; // NOLINT
+
+extern "C" {
void __sanitizer_set_report_path(const char *path) {
if (!path) return;
uptr len = internal_strlen(path);
- if (len > sizeof(__sanitizer::report_path) - 100) {
+ if (len > sizeof(report_path) - 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();
}
- internal_snprintf(__sanitizer::report_path,
- sizeof(__sanitizer::report_path), "%s.%d", path, GetPid());
- __sanitizer::report_fd = kInvalidFd;
+ internal_snprintf(report_path, sizeof(report_path), "%s.%d", path, GetPid());
+ report_fd = kInvalidFd;
+}
+
+void __sanitizer_set_report_fd(int fd) {
+ if (report_fd != kStdoutFd &&
+ report_fd != kStderrFd &&
+ report_fd != kInvalidFd)
+ internal_close(report_fd);
+ report_fd = fd;
}
+} // extern "C"
diff --git a/libsanitizer/sanitizer_common/sanitizer_common.h b/libsanitizer/sanitizer_common/sanitizer_common.h
index cddefd7ea09..e565b93af29 100644
--- a/libsanitizer/sanitizer_common/sanitizer_common.h
+++ b/libsanitizer/sanitizer_common/sanitizer_common.h
@@ -19,14 +19,24 @@
namespace __sanitizer {
// Constants.
-const uptr kWordSize = __WORDSIZE / 8;
+const uptr kWordSize = SANITIZER_WORDSIZE / 8;
const uptr kWordSizeInBits = 8 * kWordSize;
-const uptr kPageSizeBits = 12;
-const uptr kPageSize = 1UL << kPageSizeBits;
+#if defined(__powerpc__) || defined(__powerpc64__)
+// Current PPC64 kernels use 64K pages sizes, but they can be
+// configured with 4K or even other sizes.
+// We may want to use getpagesize() or sysconf(_SC_PAGESIZE) here rather than
+// hardcoding the values, but today these values need to be compile-time
+// constants.
+const uptr kPageSize = 1UL << 16;
+const uptr kCacheLineSize = 128;
+const uptr kMmapGranularity = kPageSize;
+#elif !defined(_WIN32)
+const uptr kPageSize = 1UL << 12;
const uptr kCacheLineSize = 64;
-#ifndef _WIN32
const uptr kMmapGranularity = kPageSize;
#else
+const uptr kPageSize = 1UL << 12;
+const uptr kCacheLineSize = 64;
const uptr kMmapGranularity = 1UL << 16;
#endif
@@ -96,6 +106,7 @@ void SetLowLevelAllocateCallback(LowLevelAllocateCallback callback);
// IO
void RawWrite(const char *buffer);
+bool PrintsToTty();
void Printf(const char *format, ...);
void Report(const char *format, ...);
void SetPrintfAndReportCallback(void (*callback)(const char *));
@@ -114,6 +125,7 @@ void *MapFileToMemory(const char *file_name, uptr *buff_size);
// OS
void DisableCoreDumper();
void DumpProcessMap();
+bool FileExists(const char *filename);
const char *GetEnv(const char *name);
const char *GetPwd();
void ReExec();
@@ -170,7 +182,7 @@ INLINE int ToLower(int c) {
return (c >= 'A' && c <= 'Z') ? (c + 'a' - 'A') : c;
}
-#if __WORDSIZE == 64
+#if SANITIZER_WORDSIZE == 64
# define FIRST_32_SECOND_64(a, b) (b)
#else
# define FIRST_32_SECOND_64(a, b) (a)
diff --git a/libsanitizer/sanitizer_common/sanitizer_internal_defs.h b/libsanitizer/sanitizer_common/sanitizer_internal_defs.h
index da4d049e2c6..a6795c6720b 100644
--- a/libsanitizer/sanitizer_common/sanitizer_internal_defs.h
+++ b/libsanitizer/sanitizer_common/sanitizer_internal_defs.h
@@ -22,8 +22,7 @@ using namespace __sanitizer; // NOLINT
#define WEAK SANITIZER_WEAK_ATTRIBUTE
// Platform-specific defs.
-#if defined(_WIN32)
-typedef unsigned long DWORD; // NOLINT
+#if defined(_MSC_VER)
# define ALWAYS_INLINE __declspec(forceinline)
// FIXME(timurrrr): do we need this on Windows?
# define ALIAS(x)
@@ -33,7 +32,11 @@ typedef unsigned long DWORD; // NOLINT
# define NORETURN __declspec(noreturn)
# define THREADLOCAL __declspec(thread)
# define NOTHROW
-#else // _WIN32
+# define LIKELY(x) (x)
+# define UNLIKELY(x) (x)
+# define UNUSED
+# define USED
+#else // _MSC_VER
# define ALWAYS_INLINE __attribute__((always_inline))
# define ALIAS(x) __attribute__((alias(x)))
# define ALIGNED(x) __attribute__((aligned(x)))
@@ -41,22 +44,15 @@ typedef unsigned long DWORD; // NOLINT
# define NOINLINE __attribute__((noinline))
# define NORETURN __attribute__((noreturn))
# define THREADLOCAL __thread
-# ifdef __cplusplus
-# define NOTHROW throw()
-# else
-# define NOTHROW __attribute__((__nothrow__))
-#endif
-#endif // _WIN32
-
-// We have no equivalent of these on Windows.
-#ifndef _WIN32
+# define NOTHROW throw()
# define LIKELY(x) __builtin_expect(!!(x), 1)
# define UNLIKELY(x) __builtin_expect(!!(x), 0)
# define UNUSED __attribute__((unused))
# define USED __attribute__((used))
-#endif
+#endif // _MSC_VER
#if defined(_WIN32)
+typedef unsigned long DWORD; // NOLINT
typedef DWORD thread_return_t;
# define THREAD_CALLING_CONV __stdcall
#else // _WIN32
@@ -65,15 +61,11 @@ typedef void* thread_return_t;
#endif // _WIN32
typedef thread_return_t (THREAD_CALLING_CONV *thread_callback_t)(void* arg);
-// If __WORDSIZE was undefined by the platform, define it in terms of the
-// compiler built-ins __LP64__ and _WIN64.
-#ifndef __WORDSIZE
-# if __LP64__ || defined(_WIN64)
-# define __WORDSIZE 64
-# else
-# define __WORDSIZE 32
-# endif
-#endif // __WORDSIZE
+#if __LP64__ || defined(_WIN64)
+# define SANITIZER_WORDSIZE 64
+#else
+# define SANITIZER_WORDSIZE 32
+#endif
// NOTE: Functions below must be defined in each run-time.
namespace __sanitizer {
@@ -128,7 +120,12 @@ void NORETURN CheckFailed(const char *file, int line, const char *cond,
#define DCHECK_GE(a, b)
#endif
-#define UNIMPLEMENTED() CHECK("unimplemented" && 0)
+#define UNREACHABLE(msg) do { \
+ CHECK(0 && msg); \
+ Die(); \
+} while (0)
+
+#define UNIMPLEMENTED() UNREACHABLE("unimplemented")
#define COMPILER_CHECK(pred) IMPL_COMPILER_ASSERT(pred, __LINE__)
@@ -142,13 +139,13 @@ void NORETURN CheckFailed(const char *file, int line, const char *cond,
// have stdint.h (like in Visual Studio 9).
#undef __INT64_C
#undef __UINT64_C
-#if __WORDSIZE == 64
+#if SANITIZER_WORDSIZE == 64
# define __INT64_C(c) c ## L
# define __UINT64_C(c) c ## UL
#else
# define __INT64_C(c) c ## LL
# define __UINT64_C(c) c ## ULL
-#endif // __WORDSIZE == 64
+#endif // SANITIZER_WORDSIZE == 64
#undef INT32_MIN
#define INT32_MIN (-2147483647-1)
#undef INT32_MAX
diff --git a/libsanitizer/sanitizer_common/sanitizer_libc.cc b/libsanitizer/sanitizer_common/sanitizer_libc.cc
index 21869bc4846..4d43cd7d013 100644
--- a/libsanitizer/sanitizer_common/sanitizer_libc.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_libc.cc
@@ -42,6 +42,23 @@ void *internal_memcpy(void *dest, const void *src, uptr n) {
return dest;
}
+void *internal_memmove(void *dest, const void *src, uptr n) {
+ char *d = (char*)dest;
+ char *s = (char*)src;
+ sptr i, signed_n = (sptr)n;
+ CHECK_GE(signed_n, 0);
+ if (d < s) {
+ for (i = 0; i < signed_n; ++i)
+ d[i] = s[i];
+ } else {
+ if (d > s && signed_n > 0)
+ for (i = signed_n - 1; i >= 0 ; --i) {
+ d[i] = s[i];
+ }
+ }
+ return dest;
+}
+
void *internal_memset(void* s, int c, uptr n) {
// The next line prevents Clang from making a call to memset() instead of the
// loop below.
diff --git a/libsanitizer/sanitizer_common/sanitizer_libc.h b/libsanitizer/sanitizer_common/sanitizer_libc.h
index 13528511190..4aa4a279d40 100644
--- a/libsanitizer/sanitizer_common/sanitizer_libc.h
+++ b/libsanitizer/sanitizer_common/sanitizer_libc.h
@@ -27,6 +27,7 @@ s64 internal_atoll(const char *nptr);
void *internal_memchr(const void *s, int c, uptr n);
int internal_memcmp(const void* s1, const void* s2, uptr n);
void *internal_memcpy(void *dest, const void *src, uptr n);
+void *internal_memmove(void *dest, const void *src, uptr n);
// Should not be used in performance-critical places.
void *internal_memset(void *s, int c, uptr n);
char* internal_strchr(const char *s, int c);
@@ -52,7 +53,11 @@ int internal_munmap(void *addr, uptr length);
// I/O
typedef int fd_t;
const fd_t kInvalidFd = -1;
+const fd_t kStdinFd = 0;
+const fd_t kStdoutFd = 1;
+const fd_t kStderrFd = 2;
int internal_close(fd_t fd);
+int internal_isatty(fd_t fd);
fd_t internal_open(const char *filename, bool write);
uptr internal_read(fd_t fd, void *buf, uptr count);
uptr internal_write(fd_t fd, const void *buf, uptr count);
diff --git a/libsanitizer/sanitizer_common/sanitizer_linux.cc b/libsanitizer/sanitizer_common/sanitizer_linux.cc
index f2a0d39ca99..2145aa04113 100644
--- a/libsanitizer/sanitizer_common/sanitizer_linux.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_linux.cc
@@ -30,9 +30,9 @@
#include <errno.h>
// Are we using 32-bit or 64-bit syscalls?
-// x32 (which defines __x86_64__) has __WORDSIZE == 32
+// x32 (which defines __x86_64__) has SANITIZER_WORDSIZE == 32
// but it still needs to use 64-bit syscalls.
-#if defined(__x86_64__) || __WORDSIZE == 64
+#if defined(__x86_64__) || SANITIZER_WORDSIZE == 64
# define SANITIZER_LINUX_USES_64BIT_SYSCALLS 1
#else
# define SANITIZER_LINUX_USES_64BIT_SYSCALLS 0
@@ -101,6 +101,20 @@ int internal_sched_yield() {
}
// ----------------- sanitizer_common.h
+bool FileExists(const char *filename) {
+#if SANITIZER_LINUX_USES_64BIT_SYSCALLS
+ struct stat st;
+ if (syscall(__NR_stat, filename, &st))
+ return false;
+#else
+ struct stat64 st;
+ if (syscall(__NR_stat64, filename, &st))
+ return false;
+#endif
+ // Sanity check: filename is a regular file.
+ return S_ISREG(st.st_mode);
+}
+
uptr GetTid() {
return syscall(__NR_gettid);
}
diff --git a/libsanitizer/sanitizer_common/sanitizer_mac.cc b/libsanitizer/sanitizer_common/sanitizer_mac.cc
index 400cd21842b..aa313baff92 100644
--- a/libsanitizer/sanitizer_common/sanitizer_mac.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_mac.cc
@@ -78,6 +78,14 @@ int internal_sched_yield() {
}
// ----------------- sanitizer_common.h
+bool FileExists(const char *filename) {
+ struct stat st;
+ if (stat(filename, &st))
+ return false;
+ // Sanity check: filename is a regular file.
+ return S_ISREG(st.st_mode);
+}
+
uptr GetTid() {
return reinterpret_cast<uptr>(pthread_self());
}
diff --git a/libsanitizer/sanitizer_common/sanitizer_placement_new.h b/libsanitizer/sanitizer_common/sanitizer_placement_new.h
index d149683b43d..e32d65702df 100644
--- a/libsanitizer/sanitizer_common/sanitizer_placement_new.h
+++ b/libsanitizer/sanitizer_common/sanitizer_placement_new.h
@@ -17,7 +17,7 @@
#include "sanitizer_internal_defs.h"
namespace __sanitizer {
-#if (__WORDSIZE == 64) || defined(__APPLE__)
+#if (SANITIZER_WORDSIZE == 64) || defined(__APPLE__)
typedef uptr operator_new_ptr_type;
#else
typedef u32 operator_new_ptr_type;
diff --git a/libsanitizer/sanitizer_common/sanitizer_posix.cc b/libsanitizer/sanitizer_common/sanitizer_posix.cc
index 8f71cfc049d..bd9270ecaa4 100644
--- a/libsanitizer/sanitizer_common/sanitizer_posix.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_posix.cc
@@ -72,10 +72,15 @@ void UnmapOrDie(void *addr, uptr size) {
}
void *MmapFixedNoReserve(uptr fixed_addr, uptr size) {
- return internal_mmap((void*)fixed_addr, size,
- PROT_READ | PROT_WRITE,
- MAP_PRIVATE | MAP_ANON | MAP_FIXED | MAP_NORESERVE,
- -1, 0);
+ void *p = internal_mmap((void*)(fixed_addr & ~(kPageSize - 1)),
+ RoundUpTo(size, kPageSize),
+ PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANON | MAP_FIXED | MAP_NORESERVE,
+ -1, 0);
+ if (p == (void*)-1)
+ Report("ERROR: Failed to allocate 0x%zx (%zd) bytes at address %p (%d)\n",
+ size, size, fixed_addr, errno);
+ return p;
}
void *Mprotect(uptr fixed_addr, uptr size) {
@@ -182,6 +187,10 @@ int Atexit(void (*function)(void)) {
#endif
}
+int internal_isatty(fd_t fd) {
+ return isatty(fd);
+}
+
} // namespace __sanitizer
#endif // __linux__ || __APPLE_
diff --git a/libsanitizer/sanitizer_common/sanitizer_printf.cc b/libsanitizer/sanitizer_common/sanitizer_printf.cc
index da4dc7f53a1..5876fef04f3 100644
--- a/libsanitizer/sanitizer_common/sanitizer_printf.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_printf.cc
@@ -43,7 +43,12 @@ static int AppendUnsigned(char **buff, const char *buff_end, u64 num,
num_buffer[pos++] = num % base;
num /= base;
} while (num > 0);
- while (pos < minimal_num_length) num_buffer[pos++] = 0;
+ if (pos < minimal_num_length) {
+ // Make sure compiler doesn't insert call to memset here.
+ internal_memset(&num_buffer[pos], 0,
+ sizeof(num_buffer[0]) * (minimal_num_length - pos));
+ pos = minimal_num_length;
+ }
int result = 0;
while (pos-- > 0) {
uptr digit = num_buffer[pos];
@@ -53,13 +58,16 @@ static int AppendUnsigned(char **buff, const char *buff_end, u64 num,
return result;
}
-static int AppendSignedDecimal(char **buff, const char *buff_end, s64 num) {
+static int AppendSignedDecimal(char **buff, const char *buff_end, s64 num,
+ u8 minimal_num_length) {
int result = 0;
if (num < 0) {
result += AppendChar(buff, buff_end, '-');
num = -num;
+ if (minimal_num_length)
+ --minimal_num_length;
}
- result += AppendUnsigned(buff, buff_end, (u64)num, 10, 0);
+ result += AppendUnsigned(buff, buff_end, (u64)num, 10, minimal_num_length);
return result;
}
@@ -77,14 +85,14 @@ static int AppendPointer(char **buff, const char *buff_end, u64 ptr_value) {
int result = 0;
result += AppendString(buff, buff_end, "0x");
result += AppendUnsigned(buff, buff_end, ptr_value, 16,
- (__WORDSIZE == 64) ? 12 : 8);
+ (SANITIZER_WORDSIZE == 64) ? 12 : 8);
return result;
}
int VSNPrintf(char *buff, int buff_length,
const char *format, va_list args) {
- static const char *kPrintfFormatsHelp = "Supported Printf formats: "
- "%%[z]{d,u,x}; %%p; %%s; %%c\n";
+ static const char *kPrintfFormatsHelp =
+ "Supported Printf formats: %%(0[0-9]*)?(z|ll)?{d,u,x}; %%p; %%s; %%c\n";
RAW_CHECK(format);
RAW_CHECK(buff_length > 0);
const char *buff_end = &buff[buff_length - 1];
@@ -96,42 +104,55 @@ int VSNPrintf(char *buff, int buff_length,
continue;
}
cur++;
+ bool have_width = (*cur == '0');
+ int width = 0;
+ if (have_width) {
+ while (*cur >= '0' && *cur <= '9') {
+ have_width = true;
+ width = width * 10 + *cur++ - '0';
+ }
+ }
bool have_z = (*cur == 'z');
cur += have_z;
+ bool have_ll = !have_z && (cur[0] == 'l' && cur[1] == 'l');
+ cur += have_ll * 2;
s64 dval;
u64 uval;
+ bool have_flags = have_width | have_z | have_ll;
switch (*cur) {
case 'd': {
- dval = have_z ? va_arg(args, sptr)
- : va_arg(args, int);
- result += AppendSignedDecimal(&buff, buff_end, dval);
+ dval = have_ll ? va_arg(args, s64)
+ : have_z ? va_arg(args, sptr)
+ : va_arg(args, int);
+ result += AppendSignedDecimal(&buff, buff_end, dval, width);
break;
}
case 'u':
case 'x': {
- uval = have_z ? va_arg(args, uptr)
- : va_arg(args, unsigned);
+ uval = have_ll ? va_arg(args, u64)
+ : have_z ? va_arg(args, uptr)
+ : va_arg(args, unsigned);
result += AppendUnsigned(&buff, buff_end, uval,
- (*cur == 'u') ? 10 : 16, 0);
+ (*cur == 'u') ? 10 : 16, width);
break;
}
case 'p': {
- RAW_CHECK_MSG(!have_z, kPrintfFormatsHelp);
+ RAW_CHECK_MSG(!have_flags, kPrintfFormatsHelp);
result += AppendPointer(&buff, buff_end, va_arg(args, uptr));
break;
}
case 's': {
- RAW_CHECK_MSG(!have_z, kPrintfFormatsHelp);
+ RAW_CHECK_MSG(!have_flags, kPrintfFormatsHelp);
result += AppendString(&buff, buff_end, va_arg(args, char*));
break;
}
case 'c': {
- RAW_CHECK_MSG(!have_z, kPrintfFormatsHelp);
+ RAW_CHECK_MSG(!have_flags, kPrintfFormatsHelp);
result += AppendChar(&buff, buff_end, va_arg(args, int));
break;
}
case '%' : {
- RAW_CHECK_MSG(!have_z, kPrintfFormatsHelp);
+ RAW_CHECK_MSG(!have_flags, kPrintfFormatsHelp);
result += AppendChar(&buff, buff_end, '%');
break;
}
@@ -151,7 +172,7 @@ void SetPrintfAndReportCallback(void (*callback)(const char *)) {
}
void Printf(const char *format, ...) {
- const int kLen = 1024 * 4;
+ const int kLen = 16 * 1024;
InternalScopedBuffer<char> buffer(kLen);
va_list args;
va_start(args, format);
@@ -177,7 +198,7 @@ int internal_snprintf(char *buffer, uptr length, const char *format, ...) {
// Like Printf, but prints the current PID before the output string.
void Report(const char *format, ...) {
- const int kLen = 1024 * 4;
+ const int kLen = 16 * 1024;
InternalScopedBuffer<char> buffer(kLen);
int needed_length = internal_snprintf(buffer.data(),
kLen, "==%d== ", GetPid());
diff --git a/libsanitizer/sanitizer_common/sanitizer_procmaps.h b/libsanitizer/sanitizer_common/sanitizer_procmaps.h
index 5e5e5ce89be..5541cfc0c63 100644
--- a/libsanitizer/sanitizer_common/sanitizer_procmaps.h
+++ b/libsanitizer/sanitizer_common/sanitizer_procmaps.h
@@ -23,7 +23,6 @@ class MemoryMappingLayout {
bool GetObjectNameAndOffset(uptr addr, uptr *offset,
char filename[], uptr filename_size) {
UNIMPLEMENTED();
- return false;
}
};
diff --git a/libsanitizer/sanitizer_common/sanitizer_stacktrace.cc b/libsanitizer/sanitizer_common/sanitizer_stacktrace.cc
index 915c4b8050a..037a7c3f9c0 100644
--- a/libsanitizer/sanitizer_common/sanitizer_stacktrace.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_stacktrace.cc
@@ -31,7 +31,12 @@ static uptr patch_pc(uptr pc) {
// Cancel Thumb bit.
pc = pc & (~1);
#endif
+#if defined(__powerpc__) || defined(__powerpc64__)
+ // PCs are always 4 byte aligned.
+ return pc - 4;
+#else
return pc - 1;
+#endif
}
static void PrintStackFramePrefix(uptr frame_num, uptr pc) {
@@ -75,7 +80,8 @@ void StackTrace::PrintStack(const uptr *addr, uptr size,
Printf(" %s\n", StripPathPrefix(buff.data(), strip_file_prefix));
frame_num++;
}
- } else if (symbolize) {
+ }
+ if (symbolize && addr_frames_num == 0) {
// Use our own (online) symbolizer, if necessary.
addr_frames_num = SymbolizeCode(pc, addr_frames.data(),
addr_frames.size());
@@ -135,12 +141,20 @@ void StackTrace::FastUnwindStack(uptr pc, uptr bp,
}
}
+void StackTrace::PopStackFrames(uptr count) {
+ CHECK(size >= count);
+ size -= count;
+ for (uptr i = 0; i < size; i++) {
+ trace[i] = trace[i + count];
+ }
+}
+
// On 32-bits we don't compress stack traces.
// On 64-bits we compress stack traces: if a given pc differes slightly from
// the previous one, we record a 31-bit offset instead of the full pc.
SANITIZER_INTERFACE_ATTRIBUTE
uptr StackTrace::CompressStack(StackTrace *stack, u32 *compressed, uptr size) {
-#if __WORDSIZE == 32
+#if SANITIZER_WORDSIZE == 32
// Don't compress, just copy.
uptr res = 0;
for (uptr i = 0; i < stack->size && i < size; i++) {
@@ -181,7 +195,7 @@ uptr StackTrace::CompressStack(StackTrace *stack, u32 *compressed, uptr size) {
compressed[c_index] = 0;
if (c_index + 1 < size)
compressed[c_index + 1] = 0;
-#endif // __WORDSIZE
+#endif // SANITIZER_WORDSIZE
// debug-only code
#if 0
@@ -204,7 +218,7 @@ uptr StackTrace::CompressStack(StackTrace *stack, u32 *compressed, uptr size) {
SANITIZER_INTERFACE_ATTRIBUTE
void StackTrace::UncompressStack(StackTrace *stack,
u32 *compressed, uptr size) {
-#if __WORDSIZE == 32
+#if SANITIZER_WORDSIZE == 32
// Don't uncompress, just copy.
stack->size = 0;
for (uptr i = 0; i < size && i < kStackTraceMax; i++) {
@@ -239,7 +253,7 @@ void StackTrace::UncompressStack(StackTrace *stack,
stack->trace[stack->size++] = pc;
prev_pc = pc;
}
-#endif // __WORDSIZE
+#endif // SANITIZER_WORDSIZE
}
} // namespace __sanitizer
diff --git a/libsanitizer/sanitizer_common/sanitizer_stacktrace.h b/libsanitizer/sanitizer_common/sanitizer_stacktrace.h
index a7934c65e1e..b36a1a082c5 100644
--- a/libsanitizer/sanitizer_common/sanitizer_stacktrace.h
+++ b/libsanitizer/sanitizer_common/sanitizer_stacktrace.h
@@ -43,6 +43,8 @@ struct StackTrace {
void FastUnwindStack(uptr pc, uptr bp, uptr stack_top, uptr stack_bottom);
+ void PopStackFrames(uptr count);
+
static uptr GetCurrentPc();
static uptr CompressStack(StackTrace *stack,
diff --git a/libsanitizer/sanitizer_common/sanitizer_symbolizer.cc b/libsanitizer/sanitizer_common/sanitizer_symbolizer.cc
index 66ac3c8a246..efd1e816832 100644
--- a/libsanitizer/sanitizer_common/sanitizer_symbolizer.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_symbolizer.cc
@@ -291,7 +291,8 @@ class Symbolizer {
}
}
- static const uptr kMaxNumberOfModuleContexts = 4096;
+ // 16K loaded modules should be enough for everyone.
+ static const uptr kMaxNumberOfModuleContexts = 1 << 14;
LoadedModule *modules_; // Array of module descriptions is leaked.
uptr n_modules_;
diff --git a/libsanitizer/sanitizer_common/sanitizer_symbolizer.h b/libsanitizer/sanitizer_common/sanitizer_symbolizer.h
index 83adf025282..13ec83f2cbf 100644
--- a/libsanitizer/sanitizer_common/sanitizer_symbolizer.h
+++ b/libsanitizer/sanitizer_common/sanitizer_symbolizer.h
@@ -77,7 +77,7 @@ class LoadedModule {
};
char *full_name_;
uptr base_address_;
- static const uptr kMaxNumberOfAddressRanges = 8;
+ static const uptr kMaxNumberOfAddressRanges = 6;
AddressRange ranges_[kMaxNumberOfAddressRanges];
uptr n_ranges_;
};
diff --git a/libsanitizer/sanitizer_common/sanitizer_symbolizer_linux.cc b/libsanitizer/sanitizer_common/sanitizer_symbolizer_linux.cc
index 50e39a75c3a..bb1c40f9613 100644
--- a/libsanitizer/sanitizer_common/sanitizer_symbolizer_linux.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_symbolizer_linux.cc
@@ -21,6 +21,7 @@
#include <poll.h>
#include <sys/socket.h>
#include <sys/types.h>
+#include <sys/wait.h>
#include <unistd.h>
#if !defined(__ANDROID__) && !defined(ANDROID)
@@ -29,8 +30,15 @@
namespace __sanitizer {
+static const int kSymbolizerStartupTimeMillis = 10;
+
bool StartSymbolizerSubprocess(const char *path_to_symbolizer,
int *input_fd, int *output_fd) {
+ if (!FileExists(path_to_symbolizer)) {
+ Report("WARNING: invalid path to external symbolizer!\n");
+ return false;
+ }
+
int *infd = NULL;
int *outfd = NULL;
// The client program may close its stdin and/or stdout and/or stderr
@@ -97,13 +105,23 @@ bool StartSymbolizerSubprocess(const char *path_to_symbolizer,
internal_close(infd[1]);
*input_fd = infd[0];
*output_fd = outfd[1];
+
+ // Check that symbolizer subprocess started successfully.
+ int pid_status;
+ SleepForMillis(kSymbolizerStartupTimeMillis);
+ int exited_pid = waitpid(pid, &pid_status, WNOHANG);
+ if (exited_pid != 0) {
+ // Either waitpid failed, or child has already exited.
+ Report("WARNING: external symbolizer didn't start up correctly!\n");
+ return false;
+ }
+
return true;
}
#if defined(__ANDROID__) || defined(ANDROID)
uptr GetListOfModules(LoadedModule *modules, uptr max_modules) {
UNIMPLEMENTED();
- return 0;
}
#else // ANDROID
typedef ElfW(Phdr) Elf_Phdr;
diff --git a/libsanitizer/sanitizer_common/sanitizer_symbolizer_mac.cc b/libsanitizer/sanitizer_common/sanitizer_symbolizer_mac.cc
index c5ca616d89d..a1b931b737e 100644
--- a/libsanitizer/sanitizer_common/sanitizer_symbolizer_mac.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_symbolizer_mac.cc
@@ -18,12 +18,10 @@ namespace __sanitizer {
bool StartSymbolizerSubprocess(const char *path_to_symbolizer,
int *input_fd, int *output_fd) {
UNIMPLEMENTED();
- return false;
}
uptr GetListOfModules(LoadedModule *modules, uptr max_modules) {
UNIMPLEMENTED();
- return 0;
}
} // namespace __sanitizer
diff --git a/libsanitizer/sanitizer_common/sanitizer_symbolizer_win.cc b/libsanitizer/sanitizer_common/sanitizer_symbolizer_win.cc
index 7e6ba53e128..3b81e794e59 100644
--- a/libsanitizer/sanitizer_common/sanitizer_symbolizer_win.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_symbolizer_win.cc
@@ -20,12 +20,10 @@ namespace __sanitizer {
bool StartSymbolizerSubprocess(const char *path_to_symbolizer,
int *input_fd, int *output_fd) {
UNIMPLEMENTED();
- return false;
}
uptr GetListOfModules(LoadedModule *modules, uptr max_modules) {
UNIMPLEMENTED();
- return 0;
};
} // namespace __sanitizer
diff --git a/libsanitizer/sanitizer_common/sanitizer_win.cc b/libsanitizer/sanitizer_common/sanitizer_win.cc
index 314852304d8..03a5c204c66 100644
--- a/libsanitizer/sanitizer_common/sanitizer_win.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_win.cc
@@ -10,6 +10,9 @@
// sanitizer_libc.h.
//===----------------------------------------------------------------------===//
#ifdef _WIN32
+#define WIN32_LEAN_AND_MEAN
+#define NOGDI
+#include <stdlib.h>
#include <windows.h>
#include "sanitizer_common.h"
@@ -18,6 +21,10 @@
namespace __sanitizer {
// --------------------- sanitizer_common.h
+bool FileExists(const char *filename) {
+ UNIMPLEMENTED();
+}
+
int GetPid() {
return GetProcessId(GetCurrentProcess());
}
@@ -39,7 +46,6 @@ void GetThreadStackTopAndBottom(bool at_initialization, uptr *stack_top,
*stack_bottom = (uptr)mbi.AllocationBase;
}
-
void *MmapOrDie(uptr size, const char *mem_type) {
void *rv = VirtualAlloc(0, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
if (rv == 0) {
@@ -59,8 +65,12 @@ void UnmapOrDie(void *addr, uptr size) {
}
void *MmapFixedNoReserve(uptr fixed_addr, uptr size) {
- return VirtualAlloc((LPVOID)fixed_addr, size,
- MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
+ void *p = VirtualAlloc((LPVOID)fixed_addr, size,
+ MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
+ if (p == 0)
+ Report("ERROR: Failed to allocate 0x%zx (%zd) bytes at %p (%d)\n",
+ size, size, fixed_addr, GetLastError());
+ return p;
}
void *Mprotect(uptr fixed_addr, uptr size) {
@@ -75,7 +85,6 @@ bool MemoryRangeIsAvailable(uptr range_start, uptr range_end) {
void *MapFileToMemory(const char *file_name, uptr *buff_size) {
UNIMPLEMENTED();
- return 0;
}
const char *GetEnv(const char *name) {
@@ -96,7 +105,6 @@ const char *GetEnv(const char *name) {
const char *GetPwd() {
UNIMPLEMENTED();
- return 0;
}
void DumpProcessMap() {
@@ -113,7 +121,6 @@ void ReExec() {
bool StackSizeIsUnlimited() {
UNIMPLEMENTED();
- return false;
}
void SetStackSizeLimitInBytes(uptr limit) {
@@ -137,39 +144,40 @@ void Abort() {
_exit(-1); // abort is not NORETURN on Windows.
}
+#ifndef SANITIZER_GO
int Atexit(void (*function)(void)) {
return atexit(function);
}
+#endif
// ------------------ sanitizer_libc.h
void *internal_mmap(void *addr, uptr length, int prot, int flags,
int fd, u64 offset) {
UNIMPLEMENTED();
- return 0;
}
int internal_munmap(void *addr, uptr length) {
UNIMPLEMENTED();
- return 0;
}
int internal_close(fd_t fd) {
UNIMPLEMENTED();
- return 0;
+}
+
+int internal_isatty(fd_t fd) {
+ UNIMPLEMENTED();
}
fd_t internal_open(const char *filename, bool write) {
UNIMPLEMENTED();
- return 0;
}
uptr internal_read(fd_t fd, void *buf, uptr count) {
UNIMPLEMENTED();
- return 0;
}
uptr internal_write(fd_t fd, const void *buf, uptr count) {
- if (fd != 2)
+ if (fd != kStderrFd)
UNIMPLEMENTED();
HANDLE err = GetStdHandle(STD_ERROR_HANDLE);
if (err == 0)
@@ -182,21 +190,18 @@ uptr internal_write(fd_t fd, const void *buf, uptr count) {
uptr internal_filesize(fd_t fd) {
UNIMPLEMENTED();
- return 0;
}
int internal_dup2(int oldfd, int newfd) {
UNIMPLEMENTED();
- return 0;
}
uptr internal_readlink(const char *path, char *buf, uptr bufsize) {
UNIMPLEMENTED();
- return 0;
}
int internal_sched_yield() {
- UNIMPLEMENTED();
+ Sleep(0);
return 0;
}
OpenPOWER on IntegriCloud