[Sanitizer]: Introduce a common internal printf function. For now, also use tool-specific wrappers TsanPrintf (its output is controlled by TSan flags) and AsanPrintf (which copies its results to the ASan-private buffer). Supported formats: %[z]{d,u,x}, %s, %p. Re-write all format strings in TSan according to this format (this should have no effect on 64-bit platforms).

llvm-svn: 158065
This commit is contained in:
Alexey Samsonov 2012-06-06 13:11:29 +00:00
parent 88aeaf6ac4
commit 51ae983718
29 changed files with 400 additions and 440 deletions

View File

@ -217,18 +217,18 @@ struct AsanChunk: public ChunkBase {
void DescribeAddress(uptr addr, uptr access_size) { void DescribeAddress(uptr addr, uptr access_size) {
uptr offset; uptr offset;
Printf("%p is located ", (void*)addr); AsanPrintf("%p is located ", (void*)addr);
if (AddrIsInside(addr, access_size, &offset)) { if (AddrIsInside(addr, access_size, &offset)) {
Printf("%zu bytes inside of", offset); AsanPrintf("%zu bytes inside of", offset);
} else if (AddrIsAtLeft(addr, access_size, &offset)) { } else if (AddrIsAtLeft(addr, access_size, &offset)) {
Printf("%zu bytes to the left of", offset); AsanPrintf("%zu bytes to the left of", offset);
} else if (AddrIsAtRight(addr, access_size, &offset)) { } else if (AddrIsAtRight(addr, access_size, &offset)) {
Printf("%zu bytes to the right of", offset); AsanPrintf("%zu bytes to the right of", offset);
} else { } else {
Printf(" somewhere around (this is AddressSanitizer bug!)"); AsanPrintf(" somewhere around (this is AddressSanitizer bug!)");
} }
Printf(" %zu-byte region [%p,%p)\n", AsanPrintf(" %zu-byte region [%p,%p)\n",
used_size, (void*)beg(), (void*)(beg() + used_size)); used_size, (void*)beg(), (void*)(beg() + used_size));
} }
}; };
@ -588,20 +588,20 @@ static void Describe(uptr addr, uptr access_size) {
if (m->free_tid >= 0) { if (m->free_tid >= 0) {
AsanThreadSummary *free_thread = AsanThreadSummary *free_thread =
asanThreadRegistry().FindByTid(m->free_tid); asanThreadRegistry().FindByTid(m->free_tid);
Printf("freed by thread T%d here:\n", free_thread->tid()); AsanPrintf("freed by thread T%d here:\n", free_thread->tid());
AsanStackTrace free_stack; AsanStackTrace free_stack;
AsanStackTrace::UncompressStack(&free_stack, m->compressed_free_stack(), AsanStackTrace::UncompressStack(&free_stack, m->compressed_free_stack(),
m->compressed_free_stack_size()); m->compressed_free_stack_size());
free_stack.PrintStack(); free_stack.PrintStack();
Printf("previously allocated by thread T%d here:\n", AsanPrintf("previously allocated by thread T%d here:\n",
alloc_thread->tid()); alloc_thread->tid());
alloc_stack.PrintStack(); alloc_stack.PrintStack();
t->summary()->Announce(); t->summary()->Announce();
free_thread->Announce(); free_thread->Announce();
alloc_thread->Announce(); alloc_thread->Announce();
} else { } else {
Printf("allocated by thread T%d here:\n", alloc_thread->tid()); AsanPrintf("allocated by thread T%d here:\n", alloc_thread->tid());
alloc_stack.PrintStack(); alloc_stack.PrintStack();
t->summary()->Announce(); t->summary()->Announce();
alloc_thread->Announce(); alloc_thread->Announce();
@ -711,13 +711,13 @@ static void Deallocate(u8 *ptr, AsanStackTrace *stack) {
u16 old_chunk_state = AtomicExchange(&m->chunk_state, CHUNK_QUARANTINE); u16 old_chunk_state = AtomicExchange(&m->chunk_state, CHUNK_QUARANTINE);
if (old_chunk_state == CHUNK_QUARANTINE) { if (old_chunk_state == CHUNK_QUARANTINE) {
Report("ERROR: AddressSanitizer attempting double-free on %p:\n", ptr); AsanReport("ERROR: AddressSanitizer attempting double-free on %p:\n", ptr);
stack->PrintStack(); stack->PrintStack();
Describe((uptr)ptr, 1); Describe((uptr)ptr, 1);
ShowStatsAndAbort(); ShowStatsAndAbort();
} else if (old_chunk_state != CHUNK_ALLOCATED) { } else if (old_chunk_state != CHUNK_ALLOCATED) {
Report("ERROR: AddressSanitizer attempting free on address which was not" AsanReport("ERROR: AddressSanitizer attempting free on address "
" malloc()-ed: %p\n", ptr); "which was not malloc()-ed: %p\n", ptr);
stack->PrintStack(); stack->PrintStack();
ShowStatsAndAbort(); ShowStatsAndAbort();
} }
@ -867,8 +867,9 @@ uptr asan_malloc_usable_size(void *ptr, AsanStackTrace *stack) {
if (ptr == 0) return 0; if (ptr == 0) return 0;
uptr usable_size = malloc_info.AllocationSize((uptr)ptr); uptr usable_size = malloc_info.AllocationSize((uptr)ptr);
if (FLAG_check_malloc_usable_size && (usable_size == 0)) { if (FLAG_check_malloc_usable_size && (usable_size == 0)) {
Report("ERROR: AddressSanitizer attempting to call malloc_usable_size() " AsanReport("ERROR: AddressSanitizer attempting to call "
"for pointer which is not owned: %p\n", ptr); "malloc_usable_size() for pointer which is "
"not owned: %p\n", ptr);
stack->PrintStack(); stack->PrintStack();
Describe((uptr)ptr, 1); Describe((uptr)ptr, 1);
ShowStatsAndAbort(); ShowStatsAndAbort();
@ -1072,9 +1073,9 @@ uptr __asan_get_allocated_size(const void *p) {
uptr allocated_size = malloc_info.AllocationSize((uptr)p); uptr allocated_size = malloc_info.AllocationSize((uptr)p);
// Die if p is not malloced or if it is already freed. // Die if p is not malloced or if it is already freed.
if (allocated_size == 0) { if (allocated_size == 0) {
Report("ERROR: AddressSanitizer attempting to call " AsanReport("ERROR: AddressSanitizer attempting to call "
"__asan_get_allocated_size() for pointer which is " "__asan_get_allocated_size() for pointer which is "
"not owned: %p\n", p); "not owned: %p\n", p);
PRINT_CURRENT_STACK(); PRINT_CURRENT_STACK();
Describe((uptr)p, 1); Describe((uptr)p, 1);
ShowStatsAndAbort(); ShowStatsAndAbort();

View File

@ -66,22 +66,22 @@ void PrintIfASCII(const Global &g) {
if (!isascii(*(char*)p)) return; if (!isascii(*(char*)p)) return;
} }
if (*(char*)(g.beg + g.size - 1) != 0) return; if (*(char*)(g.beg + g.size - 1) != 0) return;
Printf(" '%s' is ascii string '%s'\n", g.name, (char*)g.beg); AsanPrintf(" '%s' is ascii string '%s'\n", g.name, (char*)g.beg);
} }
bool DescribeAddrIfMyRedZone(const Global &g, uptr addr) { bool DescribeAddrIfMyRedZone(const Global &g, uptr addr) {
if (addr < g.beg - kGlobalAndStackRedzone) return false; if (addr < g.beg - kGlobalAndStackRedzone) return false;
if (addr >= g.beg + g.size_with_redzone) return false; if (addr >= g.beg + g.size_with_redzone) return false;
Printf("%p is located ", (void*)addr); AsanPrintf("%p is located ", (void*)addr);
if (addr < g.beg) { if (addr < g.beg) {
Printf("%zd bytes to the left", g.beg - addr); AsanPrintf("%zd bytes to the left", g.beg - addr);
} else if (addr >= g.beg + g.size) { } else if (addr >= g.beg + g.size) {
Printf("%zd bytes to the right", addr - (g.beg + g.size)); AsanPrintf("%zd bytes to the right", addr - (g.beg + g.size));
} else { } else {
Printf("%zd bytes inside", addr - g.beg); // Can it happen? AsanPrintf("%zd bytes inside", addr - g.beg); // Can it happen?
} }
Printf(" of global variable '%s' (0x%zx) of size %zu\n", AsanPrintf(" of global variable '%s' (0x%zx) of size %zu\n",
g.name, g.beg, g.size); g.name, g.beg, g.size);
PrintIfASCII(g); PrintIfASCII(g);
return true; return true;
} }
@ -94,8 +94,8 @@ bool DescribeAddrIfGlobal(uptr addr) {
for (ListOfGlobals *l = list_of_globals; l; l = l->next) { for (ListOfGlobals *l = list_of_globals; l; l = l->next) {
const Global &g = *l->g; const Global &g = *l->g;
if (FLAG_report_globals >= 2) if (FLAG_report_globals >= 2)
Printf("Search Global: beg=%p size=%zu name=%s\n", AsanPrintf("Search Global: beg=%p size=%zu name=%s\n",
(void*)g.beg, g.size, (char*)g.name); (void*)g.beg, g.size, (char*)g.name);
res |= DescribeAddrIfMyRedZone(g, addr); res |= DescribeAddrIfMyRedZone(g, addr);
} }
return res; return res;

View File

@ -155,9 +155,9 @@ static inline bool RangesOverlap(const char *offset1, uptr length1,
const char *offset1 = (const char*)_offset1; \ const char *offset1 = (const char*)_offset1; \
const char *offset2 = (const char*)_offset2; \ const char *offset2 = (const char*)_offset2; \
if (RangesOverlap(offset1, length1, offset2, length2)) { \ if (RangesOverlap(offset1, length1, offset2, length2)) { \
Report("ERROR: AddressSanitizer %s-param-overlap: " \ AsanReport("ERROR: AddressSanitizer %s-param-overlap: " \
"memory ranges [%p,%p) and [%p, %p) overlap\n", \ "memory ranges [%p,%p) and [%p, %p) overlap\n", \
name, offset1, offset1 + length1, offset2, offset2 + length2); \ name, offset1, offset1 + length1, offset2, offset2 + length2); \
PRINT_CURRENT_STACK(); \ PRINT_CURRENT_STACK(); \
ShowStatsAndAbort(); \ ShowStatsAndAbort(); \
} \ } \

View File

@ -157,11 +157,10 @@ void AsanTSDSet(void *tsd);
uptr ReadFileToBuffer(const char *file_name, char **buff, uptr ReadFileToBuffer(const char *file_name, char **buff,
uptr *buff_size, uptr max_len); uptr *buff_size, uptr max_len);
void AppendToErrorMessageBuffer(const char *buffer);
// asan_printf.cc // asan_printf.cc
void RawWrite(const char *buffer); void AsanPrintf(const char *format, ...) FORMAT(1, 2);
int SNPrintf(char *buffer, uptr length, const char *format, ...); void AsanReport(const char *format, ...) FORMAT(1, 2);
void Printf(const char *format, ...);
void Report(const char *format, ...);
// Don't use std::min and std::max, to minimize dependency on libstdc++. // Don't use std::min and std::max, to minimize dependency on libstdc++.
template<class T> T Min(T a, T b) { return a < b ? a : b; } template<class T> T Min(T a, T b) { return a < b ? a : b; }

View File

@ -119,14 +119,14 @@ void print_zone_for_ptr(void *ptr) {
malloc_zone_t *orig_zone = malloc_zone_from_ptr(ptr); malloc_zone_t *orig_zone = malloc_zone_from_ptr(ptr);
if (orig_zone) { if (orig_zone) {
if (orig_zone->zone_name) { if (orig_zone->zone_name) {
Printf("malloc_zone_from_ptr(%p) = %p, which is %s\n", AsanPrintf("malloc_zone_from_ptr(%p) = %p, which is %s\n",
ptr, orig_zone, orig_zone->zone_name); ptr, orig_zone, orig_zone->zone_name);
} else { } else {
Printf("malloc_zone_from_ptr(%p) = %p, which doesn't have a name\n", AsanPrintf("malloc_zone_from_ptr(%p) = %p, which doesn't have a name\n",
ptr, orig_zone); ptr, orig_zone);
} }
} else { } else {
Printf("malloc_zone_from_ptr(%p) = 0\n", ptr); AsanPrintf("malloc_zone_from_ptr(%p) = 0\n", ptr);
} }
} }
@ -146,8 +146,9 @@ void mz_free(malloc_zone_t *zone, void *ptr) {
asan_free(ptr, &stack); asan_free(ptr, &stack);
} else { } else {
// Let us just leak this memory for now. // Let us just leak this memory for now.
Printf("mz_free(%p) -- attempting to free unallocated memory.\n" AsanPrintf("mz_free(%p) -- attempting to free unallocated memory.\n"
"AddressSanitizer is ignoring this error on Mac OS now.\n", ptr); "AddressSanitizer is ignoring this error on Mac OS now.\n",
ptr);
print_zone_for_ptr(ptr); print_zone_for_ptr(ptr);
GET_STACK_TRACE_HERE_FOR_FREE(ptr); GET_STACK_TRACE_HERE_FOR_FREE(ptr);
stack.PrintStack(); stack.PrintStack();
@ -170,8 +171,9 @@ void cf_free(void *ptr, void *info) {
asan_free(ptr, &stack); asan_free(ptr, &stack);
} else { } else {
// Let us just leak this memory for now. // Let us just leak this memory for now.
Printf("cf_free(%p) -- attempting to free unallocated memory.\n" AsanPrintf("cf_free(%p) -- attempting to free unallocated memory.\n"
"AddressSanitizer is ignoring this error on Mac OS now.\n", ptr); "AddressSanitizer is ignoring this error on Mac OS now.\n",
ptr);
print_zone_for_ptr(ptr); print_zone_for_ptr(ptr);
GET_STACK_TRACE_HERE_FOR_FREE(ptr); GET_STACK_TRACE_HERE_FOR_FREE(ptr);
stack.PrintStack(); stack.PrintStack();
@ -191,8 +193,9 @@ void *mz_realloc(malloc_zone_t *zone, void *ptr, size_t size) {
// We can't recover from reallocating an unknown address, because // We can't recover from reallocating an unknown address, because
// this would require reading at most |size| bytes from // this would require reading at most |size| bytes from
// potentially unaccessible memory. // potentially unaccessible memory.
Printf("mz_realloc(%p) -- attempting to realloc unallocated memory.\n" AsanPrintf("mz_realloc(%p) -- attempting to realloc unallocated memory.\n"
"This is an unrecoverable problem, exiting now.\n", ptr); "This is an unrecoverable problem, exiting now.\n",
ptr);
print_zone_for_ptr(ptr); print_zone_for_ptr(ptr);
GET_STACK_TRACE_HERE_FOR_FREE(ptr); GET_STACK_TRACE_HERE_FOR_FREE(ptr);
stack.PrintStack(); stack.PrintStack();
@ -214,8 +217,9 @@ void *cf_realloc(void *ptr, CFIndex size, CFOptionFlags hint, void *info) {
// We can't recover from reallocating an unknown address, because // We can't recover from reallocating an unknown address, because
// this would require reading at most |size| bytes from // this would require reading at most |size| bytes from
// potentially unaccessible memory. // potentially unaccessible memory.
Printf("cf_realloc(%p) -- attempting to realloc unallocated memory.\n" AsanPrintf("cf_realloc(%p) -- attempting to realloc unallocated memory.\n"
"This is an unrecoverable problem, exiting now.\n", ptr); "This is an unrecoverable problem, exiting now.\n",
ptr);
print_zone_for_ptr(ptr); print_zone_for_ptr(ptr);
GET_STACK_TRACE_HERE_FOR_FREE(ptr); GET_STACK_TRACE_HERE_FOR_FREE(ptr);
stack.PrintStack(); stack.PrintStack();
@ -227,7 +231,7 @@ void *cf_realloc(void *ptr, CFIndex size, CFOptionFlags hint, void *info) {
void mz_destroy(malloc_zone_t* zone) { void mz_destroy(malloc_zone_t* zone) {
// A no-op -- we will not be destroyed! // A no-op -- we will not be destroyed!
Printf("mz_destroy() called -- ignoring\n"); AsanPrintf("mz_destroy() called -- ignoring\n");
} }
// from AvailabilityMacros.h // from AvailabilityMacros.h
#if defined(MAC_OS_X_VERSION_10_6) && \ #if defined(MAC_OS_X_VERSION_10_6) && \

View File

@ -86,11 +86,11 @@ static void ASAN_OnSIGSEGV(int, siginfo_t *siginfo, void *context) {
if (13 != internal_write(2, "ASAN:SIGSEGV\n", 13)) Die(); if (13 != internal_write(2, "ASAN:SIGSEGV\n", 13)) Die();
uptr pc, sp, bp; uptr pc, sp, bp;
GetPcSpBp(context, &pc, &sp, &bp); GetPcSpBp(context, &pc, &sp, &bp);
Report("ERROR: AddressSanitizer crashed on unknown address %p" AsanReport("ERROR: AddressSanitizer crashed on unknown address %p"
" (pc %p sp %p bp %p T%d)\n", " (pc %p sp %p bp %p T%d)\n",
(void*)addr, (void*)pc, (void*)sp, (void*)bp, (void*)addr, (void*)pc, (void*)sp, (void*)bp,
asanThreadRegistry().GetCurrentTidOrMinusOne()); asanThreadRegistry().GetCurrentTidOrMinusOne());
Printf("AddressSanitizer can not provide additional info. ABORTING\n"); AsanPrintf("AddressSanitizer can not provide additional info. ABORTING\n");
GET_STACK_TRACE_WITH_PC_AND_BP(kStackTraceMax, pc, bp); GET_STACK_TRACE_WITH_PC_AND_BP(kStackTraceMax, pc, bp);
stack.PrintStack(); stack.PrintStack();
ShowStatsAndAbort(); ShowStatsAndAbort();

View File

@ -17,143 +17,18 @@
#include "asan_internal.h" #include "asan_internal.h"
#include "asan_interceptors.h" #include "asan_interceptors.h"
#include "sanitizer_common/sanitizer_libc.h" #include "sanitizer_common/sanitizer_libc.h"
#include "sanitizer_common/sanitizer_common.h"
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <stdio.h>
namespace __sanitizer {
int VSNPrintf(char *buff, int buff_length, const char *format, va_list args);
} // namespace __sanitizer
namespace __asan { namespace __asan {
extern char *error_message_buffer; void AsanPrintf(const char *format, ...) {
extern uptr error_message_buffer_pos, error_message_buffer_size;
void RawWrite(const char *buffer) {
static const char *kRawWriteError = "RawWrite can't output requested buffer!";
uptr length = (uptr)internal_strlen(buffer);
if (length != internal_write(2, buffer, length)) {
internal_write(2, kRawWriteError, internal_strlen(kRawWriteError));
Die();
}
if (error_message_buffer) {
int remaining = error_message_buffer_size - error_message_buffer_pos;
internal_strncpy(error_message_buffer + error_message_buffer_pos,
buffer, remaining);
error_message_buffer[error_message_buffer_size - 1] = '\0';
// FIXME: reallocate the buffer instead of truncating the message.
error_message_buffer_pos += remaining > length ? length : remaining;
}
}
static inline int AppendChar(char **buff, const char *buff_end, char c) {
if (*buff < buff_end) {
**buff = c;
(*buff)++;
}
return 1;
}
// Appends number in a given base to buffer. If its length is less than
// "minimal_num_length", it is padded with leading zeroes.
static int AppendUnsigned(char **buff, const char *buff_end, u64 num,
u8 base, u8 minimal_num_length) {
uptr const kMaxLen = 30;
RAW_CHECK(base == 10 || base == 16);
RAW_CHECK(minimal_num_length < kMaxLen);
uptr num_buffer[kMaxLen];
uptr pos = 0;
do {
RAW_CHECK_MSG(pos < kMaxLen, "appendNumber buffer overflow");
num_buffer[pos++] = num % base;
num /= base;
} while (num > 0);
while (pos < minimal_num_length) num_buffer[pos++] = 0;
int result = 0;
while (pos-- > 0) {
uptr digit = num_buffer[pos];
result += AppendChar(buff, buff_end, (digit < 10) ? '0' + digit
: 'a' + digit - 10);
}
return result;
}
static inline int AppendSignedDecimal(char **buff, const char *buff_end,
s64 num) {
int result = 0;
if (num < 0) {
result += AppendChar(buff, buff_end, '-');
num = -num;
}
result += AppendUnsigned(buff, buff_end, (u64)num, 10, 0);
return result;
}
static inline int AppendString(char **buff, const char *buff_end,
const char *s) {
// Avoid library functions like stpcpy here.
RAW_CHECK_MSG(s, "Error: passing a 0 pointer to AppendString\n");
int result = 0;
for (; *s; s++) {
result += AppendChar(buff, buff_end, *s);
}
return result;
}
static inline 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);
return result;
}
static 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";
RAW_CHECK(format);
RAW_CHECK(buff_length > 0);
const char *buff_end = &buff[buff_length - 1];
const char *cur = format;
int result = 0;
for (; *cur; cur++) {
if (*cur == '%') {
cur++;
bool have_z = (*cur == 'z');
cur += have_z;
s64 dval;
u64 uval;
switch (*cur) {
case 'd': dval = have_z ? va_arg(args, sptr)
: va_arg(args, int);
result += AppendSignedDecimal(&buff, buff_end, dval);
break;
case 'u': uval = have_z ? va_arg(args, uptr)
: va_arg(args, unsigned);
result += AppendUnsigned(&buff, buff_end, uval, 10, 0);
break;
case 'x': uval = have_z ? va_arg(args, uptr)
: va_arg(args, unsigned);
result += AppendUnsigned(&buff, buff_end, uval, 16, 0);
break;
case 'p': RAW_CHECK_MSG(!have_z, kPrintfFormatsHelp);
result += AppendPointer(&buff, buff_end,
va_arg(args, uptr));
break;
case 's': RAW_CHECK_MSG(!have_z, kPrintfFormatsHelp);
result += AppendString(&buff, buff_end, va_arg(args, char*));
break;
default: RAW_CHECK_MSG(false, kPrintfFormatsHelp);
}
} else {
result += AppendChar(&buff, buff_end, *cur);
}
}
RAW_CHECK(buff <= buff_end);
AppendChar(&buff, buff_end + 1, '\0');
return result;
}
void Printf(const char *format, ...) {
const int kLen = 1024 * 4; const int kLen = 1024 * 4;
char buffer[kLen]; char buffer[kLen];
va_list args; va_list args;
@ -162,22 +37,11 @@ void Printf(const char *format, ...) {
va_end(args); va_end(args);
RAW_CHECK_MSG(needed_length < kLen, "Buffer in Printf is too short!\n"); RAW_CHECK_MSG(needed_length < kLen, "Buffer in Printf is too short!\n");
RawWrite(buffer); RawWrite(buffer);
AppendToErrorMessageBuffer(buffer);
} }
// Writes at most "length" symbols to "buffer" (including trailing '\0'). // Like AsanPrintf, but prints the current PID before the output string.
// Returns the number of symbols that should have been written to buffer void AsanReport(const char *format, ...) {
// (not including trailing '\0'). Thus, the string is truncated
// iff return value is not less than "length".
int SNPrintf(char *buffer, uptr length, const char *format, ...) {
va_list args;
va_start(args, format);
int needed_length = VSNPrintf(buffer, length, format, args);
va_end(args);
return needed_length;
}
// Like Printf, but prints the current PID before the output string.
void Report(const char *format, ...) {
const int kLen = 1024 * 4; const int kLen = 1024 * 4;
char buffer[kLen]; char buffer[kLen];
int needed_length = SNPrintf(buffer, kLen, "==%d== ", GetPid()); int needed_length = SNPrintf(buffer, kLen, "==%d== ", GetPid());
@ -189,6 +53,7 @@ void Report(const char *format, ...) {
va_end(args); va_end(args);
RAW_CHECK_MSG(needed_length < kLen, "Buffer in Report is too short!\n"); RAW_CHECK_MSG(needed_length < kLen, "Buffer in Report is too short!\n");
RawWrite(buffer); RawWrite(buffer);
AppendToErrorMessageBuffer(buffer);
} }
} // namespace __asan } // namespace __asan

View File

@ -95,11 +95,11 @@ void ShowStatsAndAbort() {
static void PrintBytes(const char *before, uptr *a) { static void PrintBytes(const char *before, uptr *a) {
u8 *bytes = (u8*)a; u8 *bytes = (u8*)a;
uptr byte_num = (__WORDSIZE) / 8; uptr byte_num = (__WORDSIZE) / 8;
Printf("%s%p:", before, (void*)a); AsanPrintf("%s%p:", before, (void*)a);
for (uptr i = 0; i < byte_num; i++) { for (uptr i = 0; i < byte_num; i++) {
Printf(" %x%x", bytes[i] >> 4, bytes[i] & 15); AsanPrintf(" %x%x", bytes[i] >> 4, bytes[i] & 15);
} }
Printf("\n"); AsanPrintf("\n");
} }
uptr ReadFileToBuffer(const char *file_name, char **buff, uptr ReadFileToBuffer(const char *file_name, char **buff,
@ -133,11 +133,23 @@ uptr ReadFileToBuffer(const char *file_name, char **buff,
return read_len; return read_len;
} }
void AppendToErrorMessageBuffer(const char *buffer) {
if (error_message_buffer) {
uptr length = (uptr)internal_strlen(buffer);
int remaining = error_message_buffer_size - error_message_buffer_pos;
internal_strncpy(error_message_buffer + error_message_buffer_pos,
buffer, remaining);
error_message_buffer[error_message_buffer_size - 1] = '\0';
// FIXME: reallocate the buffer instead of truncating the message.
error_message_buffer_pos += remaining > length ? length : remaining;
}
}
// ---------------------- mmap -------------------- {{{1 // ---------------------- mmap -------------------- {{{1
void OutOfMemoryMessageAndDie(const char *mem_type, uptr size) { void OutOfMemoryMessageAndDie(const char *mem_type, uptr size) {
Report("ERROR: AddressSanitizer failed to allocate " AsanReport("ERROR: AddressSanitizer failed to allocate "
"0x%zx (%zd) bytes of %s\n", "0x%zx (%zd) bytes of %s\n",
size, size, mem_type); size, size, mem_type);
PRINT_CURRENT_STACK(); PRINT_CURRENT_STACK();
ShowStatsAndAbort(); ShowStatsAndAbort();
} }
@ -187,14 +199,14 @@ static bool DescribeStackAddress(uptr addr, uptr access_size) {
internal_strncat(buf, frame_descr, internal_strncat(buf, frame_descr,
Min(kBufSize, Min(kBufSize,
static_cast<sptr>(name_end - frame_descr))); static_cast<sptr>(name_end - frame_descr)));
Printf("Address %p is located at offset %zu " AsanPrintf("Address %p is located at offset %zu "
"in frame <%s> of T%d's stack:\n", "in frame <%s> of T%d's stack:\n",
(void*)addr, offset, buf, t->tid()); (void*)addr, offset, buf, t->tid());
// Report the number of stack objects. // Report the number of stack objects.
char *p; char *p;
uptr n_objects = internal_simple_strtoll(name_end, &p, 10); uptr n_objects = internal_simple_strtoll(name_end, &p, 10);
CHECK(n_objects > 0); CHECK(n_objects > 0);
Printf(" This frame has %zu object(s):\n", n_objects); AsanPrintf(" This frame has %zu object(s):\n", n_objects);
// Report all objects in this frame. // Report all objects in this frame.
for (uptr i = 0; i < n_objects; i++) { for (uptr i = 0; i < n_objects; i++) {
uptr beg, size; uptr beg, size;
@ -203,19 +215,19 @@ static bool DescribeStackAddress(uptr addr, uptr access_size) {
size = internal_simple_strtoll(p, &p, 10); size = internal_simple_strtoll(p, &p, 10);
len = internal_simple_strtoll(p, &p, 10); len = internal_simple_strtoll(p, &p, 10);
if (beg <= 0 || size <= 0 || len < 0 || *p != ' ') { if (beg <= 0 || size <= 0 || len < 0 || *p != ' ') {
Printf("AddressSanitizer can't parse the stack frame descriptor: |%s|\n", AsanPrintf("AddressSanitizer can't parse the stack frame "
frame_descr); "descriptor: |%s|\n", frame_descr);
break; break;
} }
p++; p++;
buf[0] = 0; buf[0] = 0;
internal_strncat(buf, p, Min(kBufSize, len)); internal_strncat(buf, p, Min(kBufSize, len));
p += len; p += len;
Printf(" [%zu, %zu) '%s'\n", beg, beg + size, buf); AsanPrintf(" [%zu, %zu) '%s'\n", beg, beg + size, buf);
} }
Printf("HINT: this may be a false positive if your program uses " AsanPrintf("HINT: this may be a false positive if your program uses "
"some custom stack unwind mechanism\n" "some custom stack unwind mechanism\n"
" (longjmp and C++ exceptions *are* supported)\n"); " (longjmp and C++ exceptions *are* supported)\n");
t->summary()->Announce(); t->summary()->Announce();
return true; return true;
} }
@ -320,7 +332,7 @@ static void BoolFlagValue(const char *flags, const char *flag,
} }
static void asan_atexit() { static void asan_atexit() {
Printf("AddressSanitizer exit stats:\n"); AsanPrintf("AddressSanitizer exit stats:\n");
__asan_print_accumulated_stats(); __asan_print_accumulated_stats();
} }
@ -370,7 +382,8 @@ void __asan_report_error(uptr pc, uptr bp, uptr sp,
static int num_calls = 0; static int num_calls = 0;
if (AtomicInc(&num_calls) > 1) return; if (AtomicInc(&num_calls) > 1) return;
Printf("=================================================================\n"); AsanPrintf("===================================================="
"=============\n");
const char *bug_descr = "unknown-crash"; const char *bug_descr = "unknown-crash";
if (AddrIsInMem(addr)) { if (AddrIsInMem(addr)) {
u8 *shadow_addr = (u8*)MemToShadow(addr); u8 *shadow_addr = (u8*)MemToShadow(addr);
@ -417,13 +430,13 @@ void __asan_report_error(uptr pc, uptr bp, uptr sp,
curr_thread->fake_stack().StopUsingFakeStack(); curr_thread->fake_stack().StopUsingFakeStack();
} }
Report("ERROR: AddressSanitizer %s on address " AsanReport("ERROR: AddressSanitizer %s on address "
"%p at pc 0x%zx bp 0x%zx sp 0x%zx\n", "%p at pc 0x%zx bp 0x%zx sp 0x%zx\n",
bug_descr, (void*)addr, pc, bp, sp); bug_descr, (void*)addr, pc, bp, sp);
Printf("%s of size %zu at %p thread T%d\n", AsanPrintf("%s of size %zu at %p thread T%d\n",
access_size ? (is_write ? "WRITE" : "READ") : "ACCESS", access_size ? (is_write ? "WRITE" : "READ") : "ACCESS",
access_size, (void*)addr, curr_tid); access_size, (void*)addr, curr_tid);
if (FLAG_debug) { if (FLAG_debug) {
PrintBytes("PC: ", (uptr*)pc); PrintBytes("PC: ", (uptr*)pc);
@ -437,13 +450,13 @@ void __asan_report_error(uptr pc, uptr bp, uptr sp,
DescribeAddress(addr, access_size); DescribeAddress(addr, access_size);
uptr shadow_addr = MemToShadow(addr); uptr shadow_addr = MemToShadow(addr);
Report("ABORTING\n"); AsanReport("ABORTING\n");
__asan_print_accumulated_stats(); __asan_print_accumulated_stats();
Printf("Shadow byte and word:\n"); AsanPrintf("Shadow byte and word:\n");
Printf(" %p: %x\n", (void*)shadow_addr, *(unsigned char*)shadow_addr); AsanPrintf(" %p: %x\n", (void*)shadow_addr, *(unsigned char*)shadow_addr);
uptr aligned_shadow = shadow_addr & ~(kWordSize - 1); uptr aligned_shadow = shadow_addr & ~(kWordSize - 1);
PrintBytes(" ", (uptr*)(aligned_shadow)); PrintBytes(" ", (uptr*)(aligned_shadow));
Printf("More shadow bytes:\n"); AsanPrintf("More shadow bytes:\n");
PrintBytes(" ", (uptr*)(aligned_shadow-4*kWordSize)); PrintBytes(" ", (uptr*)(aligned_shadow-4*kWordSize));
PrintBytes(" ", (uptr*)(aligned_shadow-3*kWordSize)); PrintBytes(" ", (uptr*)(aligned_shadow-3*kWordSize));
PrintBytes(" ", (uptr*)(aligned_shadow-2*kWordSize)); PrintBytes(" ", (uptr*)(aligned_shadow-2*kWordSize));

View File

@ -33,7 +33,7 @@ void AsanStackTrace::PrintStack(uptr *addr, uptr size) {
uptr pc = addr[i]; uptr pc = addr[i];
char buff[4096]; char buff[4096];
ASAN_USE_EXTERNAL_SYMBOLIZER((void*)pc, buff, sizeof(buff)); ASAN_USE_EXTERNAL_SYMBOLIZER((void*)pc, buff, sizeof(buff));
Printf(" #%zu 0x%zx %s\n", i, pc, buff); AsanPrintf(" #%zu 0x%zx %s\n", i, pc, buff);
} }
} }
@ -51,19 +51,19 @@ void AsanStackTrace::PrintStack(uptr *addr, uptr size) {
for (AddressInfoList *entry = address_info_list; entry; for (AddressInfoList *entry = address_info_list; entry;
entry = entry->next) { entry = entry->next) {
AddressInfo info = entry->info; AddressInfo info = entry->info;
Printf(" #%zu 0x%zx %s:%d:%d\n", frame_num, pc, AsanPrintf(" #%zu 0x%zx %s:%d:%d\n", frame_num, pc,
(info.file) ? info.file : "", (info.file) ? info.file : "",
info.line, info.column); info.line, info.column);
frame_num++; frame_num++;
} }
address_info_list->Clear(); address_info_list->Clear();
} else { } else {
if (proc_maps.GetObjectNameAndOffset(pc, &offset, if (proc_maps.GetObjectNameAndOffset(pc, &offset,
filename, sizeof(filename))) { filename, sizeof(filename))) {
Printf(" #%zu 0x%zx (%s+0x%zx)\n", frame_num, pc, filename, AsanPrintf(" #%zu 0x%zx (%s+0x%zx)\n", frame_num, pc, filename,
offset); offset);
} else { } else {
Printf(" #%zu 0x%zx\n", frame_num, pc); AsanPrintf(" #%zu 0x%zx\n", frame_num, pc);
} }
frame_num++; frame_num++;
} }

View File

@ -27,30 +27,30 @@ AsanStats::AsanStats() {
static void PrintMallocStatsArray(const char *prefix, static void PrintMallocStatsArray(const char *prefix,
uptr (&array)[kNumberOfSizeClasses]) { uptr (&array)[kNumberOfSizeClasses]) {
Printf("%s", prefix); AsanPrintf("%s", prefix);
for (uptr i = 0; i < kNumberOfSizeClasses; i++) { for (uptr i = 0; i < kNumberOfSizeClasses; i++) {
if (!array[i]) continue; if (!array[i]) continue;
Printf("%zu:%zu; ", i, array[i]); AsanPrintf("%zu:%zu; ", i, array[i]);
} }
Printf("\n"); AsanPrintf("\n");
} }
void AsanStats::Print() { void AsanStats::Print() {
Printf("Stats: %zuM malloced (%zuM for red zones) by %zu calls\n", AsanPrintf("Stats: %zuM malloced (%zuM for red zones) by %zu calls\n",
malloced>>20, malloced_redzones>>20, mallocs); malloced>>20, malloced_redzones>>20, mallocs);
Printf("Stats: %zuM realloced by %zu calls\n", realloced>>20, reallocs); AsanPrintf("Stats: %zuM realloced by %zu calls\n", realloced>>20, reallocs);
Printf("Stats: %zuM freed by %zu calls\n", freed>>20, frees); AsanPrintf("Stats: %zuM freed by %zu calls\n", freed>>20, frees);
Printf("Stats: %zuM really freed by %zu calls\n", AsanPrintf("Stats: %zuM really freed by %zu calls\n",
really_freed>>20, real_frees); really_freed>>20, real_frees);
Printf("Stats: %zuM (%zu full pages) mmaped in %zu calls\n", AsanPrintf("Stats: %zuM (%zu full pages) mmaped in %zu calls\n",
mmaped>>20, mmaped / kPageSize, mmaps); mmaped>>20, mmaped / kPageSize, mmaps);
PrintMallocStatsArray(" mmaps by size class: ", mmaped_by_size); PrintMallocStatsArray(" mmaps by size class: ", mmaped_by_size);
PrintMallocStatsArray(" mallocs by size class: ", malloced_by_size); PrintMallocStatsArray(" mallocs by size class: ", malloced_by_size);
PrintMallocStatsArray(" frees by size class: ", freed_by_size); PrintMallocStatsArray(" frees by size class: ", freed_by_size);
PrintMallocStatsArray(" rfrees by size class: ", really_freed_by_size); PrintMallocStatsArray(" rfrees by size class: ", really_freed_by_size);
Printf("Stats: malloc large: %zu small slow: %zu\n", AsanPrintf("Stats: malloc large: %zu small slow: %zu\n",
malloc_large, malloc_small_slow); malloc_large, malloc_small_slow);
} }
static AsanLock print_lock(LINKER_INITIALIZED); static AsanLock print_lock(LINKER_INITIALIZED);

View File

@ -41,7 +41,7 @@ class AsanThreadSummary {
if (tid_ == 0) return; // no need to announce the main thread. if (tid_ == 0) return; // no need to announce the main thread.
if (!announced_) { if (!announced_) {
announced_ = true; announced_ = true;
Printf("Thread T%d created by T%d here:\n", tid_, parent_tid_); AsanPrintf("Thread T%d created by T%d here:\n", tid_, parent_tid_);
stack_.PrintStack(); stack_.PrintStack();
} }
} }

View File

@ -35,6 +35,10 @@ void RawWrite(const char *buffer);
void *MmapOrDie(uptr size); void *MmapOrDie(uptr size);
void UnmapOrDie(void *addr, uptr size); void UnmapOrDie(void *addr, uptr size);
void Printf(const char *format, ...) FORMAT(1, 2);
int SNPrintf(char *buffer, uptr length, const char *format, ...) FORMAT(3, 4);
void Report(const char *format, ...) FORMAT(1, 2);
// Bit twiddling. // Bit twiddling.
inline bool IsPowerOfTwo(uptr x) { inline bool IsPowerOfTwo(uptr x) {
return (x & (x - 1)) == 0; return (x & (x - 1)) == 0;

View File

@ -0,0 +1,185 @@
//===-- sanitizer_printf.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.
//
// Internal printf function, used inside run-time libraries.
// We can't use libc printf because we intercept some of the functions used
// inside it.
//===----------------------------------------------------------------------===//
#include "sanitizer_common.h"
#include "sanitizer_libc.h"
#include <stdio.h>
#include <stdarg.h>
namespace __sanitizer {
static int AppendChar(char **buff, const char *buff_end, char c) {
if (*buff < buff_end) {
**buff = c;
(*buff)++;
}
return 1;
}
// Appends number in a given base to buffer. If its length is less than
// "minimal_num_length", it is padded with leading zeroes.
static int AppendUnsigned(char **buff, const char *buff_end, u64 num,
u8 base, u8 minimal_num_length) {
uptr const kMaxLen = 30;
RAW_CHECK(base == 10 || base == 16);
RAW_CHECK(minimal_num_length < kMaxLen);
uptr num_buffer[kMaxLen];
uptr pos = 0;
do {
RAW_CHECK_MSG(pos < kMaxLen, "appendNumber buffer overflow");
num_buffer[pos++] = num % base;
num /= base;
} while (num > 0);
while (pos < minimal_num_length) num_buffer[pos++] = 0;
int result = 0;
while (pos-- > 0) {
uptr digit = num_buffer[pos];
result += AppendChar(buff, buff_end, (digit < 10) ? '0' + digit
: 'a' + digit - 10);
}
return result;
}
static int AppendSignedDecimal(char **buff, const char *buff_end, s64 num) {
int result = 0;
if (num < 0) {
result += AppendChar(buff, buff_end, '-');
num = -num;
}
result += AppendUnsigned(buff, buff_end, (u64)num, 10, 0);
return result;
}
static int AppendString(char **buff, const char *buff_end, const char *s) {
if (s == 0)
s = "<null>";
int result = 0;
for (; *s; s++) {
result += AppendChar(buff, buff_end, *s);
}
return result;
}
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);
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\n";
RAW_CHECK(format);
RAW_CHECK(buff_length > 0);
const char *buff_end = &buff[buff_length - 1];
const char *cur = format;
int result = 0;
for (; *cur; cur++) {
if (*cur != '%') {
result += AppendChar(&buff, buff_end, *cur);
continue;
}
cur++;
bool have_z = (*cur == 'z');
cur += have_z;
s64 dval;
u64 uval;
switch (*cur) {
case 'd': {
dval = have_z ? va_arg(args, sptr)
: va_arg(args, int);
result += AppendSignedDecimal(&buff, buff_end, dval);
break;
}
case 'u':
case 'x': {
uval = have_z ? va_arg(args, uptr)
: va_arg(args, unsigned);
result += AppendUnsigned(&buff, buff_end, uval,
(*cur == 'u') ? 10 : 16, 0);
break;
}
case 'p': {
RAW_CHECK_MSG(!have_z, kPrintfFormatsHelp);
result += AppendPointer(&buff, buff_end, va_arg(args, uptr));
break;
}
case 's': {
RAW_CHECK_MSG(!have_z, kPrintfFormatsHelp);
result += AppendString(&buff, buff_end, va_arg(args, char*));
break;
}
case '%' : {
RAW_CHECK_MSG(!have_z, kPrintfFormatsHelp);
result += AppendChar(&buff, buff_end, '%');
break;
}
default: {
RAW_CHECK_MSG(false, kPrintfFormatsHelp);
}
}
}
RAW_CHECK(buff <= buff_end);
AppendChar(&buff, buff_end + 1, '\0');
return result;
}
void Printf(const char *format, ...) {
const int kLen = 1024 * 4;
char *buffer = (char*)MmapOrDie(kLen);
va_list args;
va_start(args, format);
int needed_length = VSNPrintf(buffer, kLen, format, args);
va_end(args);
RAW_CHECK_MSG(needed_length < kLen, "Buffer in Printf is too short!\n");
RawWrite(buffer);
UnmapOrDie(buffer, kLen);
}
// Writes at most "length" symbols to "buffer" (including trailing '\0').
// Returns the number of symbols that should have been written to buffer
// (not including trailing '\0'). Thus, the string is truncated
// iff return value is not less than "length".
int SNPrintf(char *buffer, uptr length, const char *format, ...) {
va_list args;
va_start(args, format);
int needed_length = VSNPrintf(buffer, length, format, args);
va_end(args);
return needed_length;
}
// Like Printf, but prints the current PID before the output string.
void Report(const char *format, ...) {
const int kLen = 1024 * 4;
char *buffer = (char*)MmapOrDie(kLen);
int needed_length = SNPrintf(buffer, kLen, "==%d== ", GetPid());
RAW_CHECK_MSG(needed_length < kLen, "Buffer in Report is too short!\n");
va_list args;
va_start(args, format);
needed_length += VSNPrintf(buffer + needed_length, kLen - needed_length,
format, args);
va_end(args);
RAW_CHECK_MSG(needed_length < kLen, "Buffer in Report is too short!\n");
RawWrite(buffer);
UnmapOrDie(buffer, kLen);
}
} // namespace __sanitizer

View File

@ -679,7 +679,7 @@ TSAN_INTERCEPTOR(int, pthread_create,
// We place the huge ThreadState object into TLS, account for that. // We place the huge ThreadState object into TLS, account for that.
const uptr minstacksize = GetTlsSize() + 128*1024; const uptr minstacksize = GetTlsSize() + 128*1024;
if (stacksize < minstacksize) { if (stacksize < minstacksize) {
DPrintf("ThreadSanitizer: stacksize %lu->%lu\n", stacksize, minstacksize); DPrintf("ThreadSanitizer: stacksize %zu->%zu\n", stacksize, minstacksize);
pthread_attr_setstacksize(attr, minstacksize); pthread_attr_setstacksize(attr, minstacksize);
} }
ThreadParam p; ThreadParam p;

View File

@ -125,7 +125,7 @@ static bool CheckContains(ExpectRace *list, uptr addr, uptr size) {
ExpectRace *race = FindRace(list, addr, size); ExpectRace *race = FindRace(list, addr, size);
if (race == 0) if (race == 0)
return false; return false;
DPrintf("Hit expected/benign race: %s addr=%lx:%d %s:%d\n", DPrintf("Hit expected/benign race: %s addr=%zx:%d %s:%d\n",
race->desc, race->addr, (int)race->size, race->file, race->line); race->desc, race->addr, (int)race->size, race->file, race->line);
race->hitcount++; race->hitcount++;
return true; return true;
@ -217,7 +217,7 @@ void AnnotateNoOp(char *f, int l, uptr mem) {
static void ReportMissedExpectedRace(ExpectRace *race) { static void ReportMissedExpectedRace(ExpectRace *race) {
TsanPrintf("==================\n"); TsanPrintf("==================\n");
TsanPrintf("WARNING: ThreadSanitizer: missed expected data race\n"); TsanPrintf("WARNING: ThreadSanitizer: missed expected data race\n");
TsanPrintf(" %s addr=%lx %s:%d\n", TsanPrintf(" %s addr=%zx %s:%d\n",
race->desc, race->addr, race->file, race->line); race->desc, race->addr, race->file, race->line);
TsanPrintf("==================\n"); TsanPrintf("==================\n");
} }
@ -267,14 +267,14 @@ void AnnotateExpectRace(char *f, int l, uptr mem, char *desc) {
Lock lock(&dyn_ann_ctx->mtx); Lock lock(&dyn_ann_ctx->mtx);
AddExpectRace(&dyn_ann_ctx->expect, AddExpectRace(&dyn_ann_ctx->expect,
f, l, mem, 1, desc); f, l, mem, 1, desc);
DPrintf("Add expected race: %s addr=%lx %s:%d\n", desc, mem, f, l); DPrintf("Add expected race: %s addr=%zx %s:%d\n", desc, mem, f, l);
} }
static void BenignRaceImpl(char *f, int l, uptr mem, uptr size, char *desc) { static void BenignRaceImpl(char *f, int l, uptr mem, uptr size, char *desc) {
Lock lock(&dyn_ann_ctx->mtx); Lock lock(&dyn_ann_ctx->mtx);
AddExpectRace(&dyn_ann_ctx->benign, AddExpectRace(&dyn_ann_ctx->benign,
f, l, mem, size, desc); f, l, mem, size, desc);
DPrintf("Add benign race: %s addr=%lx %s:%d\n", desc, mem, f, l); DPrintf("Add benign race: %s addr=%zx %s:%d\n", desc, mem, f, l);
} }
// FIXME: Turn it off later. WTF is benign race?1?? Go talk to Hans Boehm. // FIXME: Turn it off later. WTF is benign race?1?? Go talk to Hans Boehm.

View File

@ -40,7 +40,7 @@ void *user_alloc(ThreadState *thr, uptr pc, uptr sz) {
if (CTX() && CTX()->initialized) { if (CTX() && CTX()->initialized) {
MemoryResetRange(thr, pc, (uptr)p, sz); MemoryResetRange(thr, pc, (uptr)p, sz);
} }
DPrintf("#%d: alloc(%lu) = %p\n", thr->tid, sz, p); DPrintf("#%d: alloc(%zu) = %p\n", thr->tid, sz, p);
SignalUnsafeCall(thr, pc); SignalUnsafeCall(thr, pc);
return p; return p;
} }
@ -92,7 +92,7 @@ MBlock *user_mblock(ThreadState *thr, void *p) {
MBlock *b = (MBlock*)AllocBlock(p); MBlock *b = (MBlock*)AllocBlock(p);
// FIXME: Output a warning, it's a user error. // FIXME: Output a warning, it's a user error.
if (p < (char*)(b + 1) || p > (char*)(b + 1) + b->size) { if (p < (char*)(b + 1) || p > (char*)(b + 1) + b->size) {
TsanPrintf("user_mblock p=%p b=%p size=%lu beg=%p end=%p\n", TsanPrintf("user_mblock p=%p b=%p size=%zu beg=%p end=%p\n",
p, b, b->size, (char*)(b + 1), (char*)(b + 1) + b->size); p, b, b->size, (char*)(b + 1), (char*)(b + 1) + b->size);
CHECK_GE(p, (char*)(b + 1)); CHECK_GE(p, (char*)(b + 1));
CHECK_LE(p, (char*)(b + 1) + b->size); CHECK_LE(p, (char*)(b + 1) + b->size);

View File

@ -120,7 +120,7 @@ DeadlockDetector::DeadlockDetector() {
} }
void DeadlockDetector::Lock(MutexType t) { void DeadlockDetector::Lock(MutexType t) {
// TsanPrintf("LOCK %d @%llu\n", t, seq_ + 1); // TsanPrintf("LOCK %d @%zu\n", t, seq_ + 1);
u64 max_seq = 0; u64 max_seq = 0;
u64 max_idx = MutexTypeInvalid; u64 max_idx = MutexTypeInvalid;
for (int i = 0; i != MutexTypeCount; i++) { for (int i = 0; i != MutexTypeCount; i++) {
@ -135,16 +135,17 @@ void DeadlockDetector::Lock(MutexType t) {
locked_[t] = ++seq_; locked_[t] = ++seq_;
if (max_idx == MutexTypeInvalid) if (max_idx == MutexTypeInvalid)
return; return;
// TsanPrintf(" last %d @%llu\n", max_idx, max_seq); // TsanPrintf(" last %d @%zu\n", max_idx, max_seq);
if (!CanLockAdj[max_idx][t]) { if (!CanLockAdj[max_idx][t]) {
TsanPrintf("ThreadSanitizer: internal deadlock detected\n"); TsanPrintf("ThreadSanitizer: internal deadlock detected\n");
TsanPrintf("ThreadSanitizer: can't lock %d while under %llu\n", t, max_idx); TsanPrintf("ThreadSanitizer: can't lock %d while under %zu\n",
t, (uptr)max_idx);
Die(); Die();
} }
} }
void DeadlockDetector::Unlock(MutexType t) { void DeadlockDetector::Unlock(MutexType t) {
// TsanPrintf("UNLO %d @%llu #%llu\n", t, seq_, locked_[t]); // TsanPrintf("UNLO %d @%zu #%zu\n", t, seq_, locked_[t]);
CHECK(locked_[t]); CHECK(locked_[t]);
locked_[t] = 0; locked_[t] = 0;
} }

View File

@ -96,7 +96,7 @@ static void ProtectRange(uptr beg, uptr end) {
PROT_NONE, PROT_NONE,
MAP_PRIVATE | MAP_ANON | MAP_FIXED | MAP_NORESERVE, MAP_PRIVATE | MAP_ANON | MAP_FIXED | MAP_NORESERVE,
-1, 0)) { -1, 0)) {
TsanPrintf("FATAL: ThreadSanitizer can not protect [%lx,%lx]\n", beg, end); TsanPrintf("FATAL: ThreadSanitizer can not protect [%zx,%zx]\n", beg, end);
TsanPrintf("FATAL: Make sure you are not using unlimited stack\n"); TsanPrintf("FATAL: Make sure you are not using unlimited stack\n");
Die(); Die();
} }
@ -120,17 +120,17 @@ void InitializeShadowMemory() {
} }
ProtectRange(kClosedLowBeg, kClosedLowEnd); ProtectRange(kClosedLowBeg, kClosedLowEnd);
ProtectRange(kClosedMidBeg, kClosedMidEnd); ProtectRange(kClosedMidBeg, kClosedMidEnd);
DPrintf("kClosedLow %lx-%lx (%luGB)\n", DPrintf("kClosedLow %zx-%zx (%zuGB)\n",
kClosedLowBeg, kClosedLowEnd, (kClosedLowEnd - kClosedLowBeg) >> 30); kClosedLowBeg, kClosedLowEnd, (kClosedLowEnd - kClosedLowBeg) >> 30);
DPrintf("kLinuxShadow %lx-%lx (%luGB)\n", DPrintf("kLinuxShadow %zx-%zx (%zuGB)\n",
kLinuxShadowBeg, kLinuxShadowEnd, kLinuxShadowBeg, kLinuxShadowEnd,
(kLinuxShadowEnd - kLinuxShadowBeg) >> 30); (kLinuxShadowEnd - kLinuxShadowBeg) >> 30);
DPrintf("kClosedMid %lx-%lx (%luGB)\n", DPrintf("kClosedMid %zx-%zx (%zuGB)\n",
kClosedMidBeg, kClosedMidEnd, (kClosedMidEnd - kClosedMidBeg) >> 30); kClosedMidBeg, kClosedMidEnd, (kClosedMidEnd - kClosedMidBeg) >> 30);
DPrintf("kLinuxAppMem %lx-%lx (%luGB)\n", DPrintf("kLinuxAppMem %zx-%zx (%zuGB)\n",
kLinuxAppMemBeg, kLinuxAppMemEnd, kLinuxAppMemBeg, kLinuxAppMemEnd,
(kLinuxAppMemEnd - kLinuxAppMemBeg) >> 30); (kLinuxAppMemEnd - kLinuxAppMemBeg) >> 30);
DPrintf("stack %lx\n", (uptr)&shadow); DPrintf("stack %zx\n", (uptr)&shadow);
} }
static void CheckPIE() { static void CheckPIE() {
@ -144,8 +144,8 @@ static void CheckPIE() {
u64 addr = strtoll(buf, 0, 16); u64 addr = strtoll(buf, 0, 16);
if ((u64)addr < kLinuxAppMemBeg) { if ((u64)addr < kLinuxAppMemBeg) {
TsanPrintf("FATAL: ThreadSanitizer can not mmap the shadow memory (" TsanPrintf("FATAL: ThreadSanitizer can not mmap the shadow memory ("
"something is mapped at 0x%llx < 0x%lx)\n", "something is mapped at 0x%zx < 0x%zx)\n",
addr, kLinuxAppMemBeg); (uptr)addr, kLinuxAppMemBeg);
TsanPrintf("FATAL: Make sure to compile with -fPIE" TsanPrintf("FATAL: Make sure to compile with -fPIE"
" and to link with -pie.\n"); " and to link with -pie.\n");
Die(); Die();

View File

@ -18,114 +18,12 @@
#include <stdarg.h> // va_list #include <stdarg.h> // va_list
typedef long long i64; // NOLINT namespace __sanitizer {
typedef long iptr; // NOLINT int VSNPrintf(char *buff, int buff_length, const char *format, va_list args);
} // namespace __sanitizer
namespace __tsan { namespace __tsan {
static int AppendChar(char **buff, const char *buff_end, char c) {
if (*buff < buff_end) {
**buff = c;
(*buff)++;
}
return 1;
}
static int AppendUnsigned(char **buff, const char *buff_end, u64 num,
int base, uptr minimal_num_length) {
uptr const kMaxLen = 30;
uptr num_buffer[kMaxLen];
uptr pos = 0;
do {
num_buffer[pos++] = num % base;
num /= base;
} while (num > 0);
while (pos < minimal_num_length) num_buffer[pos++] = 0;
int result = 0;
while (pos-- > 0) {
uptr digit = num_buffer[pos];
result += AppendChar(buff, buff_end, (digit < 10) ? '0' + digit
: 'a' + digit - 10);
}
return result;
}
static int AppendSignedDecimal(char **buff, const char *buff_end, i64 num) {
int result = 0;
if (num < 0) {
result += AppendChar(buff, buff_end, '-');
num = -num;
}
result += AppendUnsigned(buff, buff_end, (u64)num, 10, 0);
return result;
}
static int AppendString(char **buff, const char *buff_end, const char *s) {
if (s == 0)
s = "<null>";
int result = 0;
for (; *s; s++) {
result += AppendChar(buff, buff_end, *s);
}
return result;
}
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,
(sizeof(void*) == 8) ? 12 : 8); // NOLINT
return result;
}
uptr VSNPrintf(char *buff, int buff_length,
const char *format, va_list args) {
const char *buff_end = &buff[buff_length - 1];
const char *cur = format;
int result = 0;
for (; *cur; cur++) {
if (*cur != '%') {
result += AppendChar(&buff, buff_end, *cur);
continue;
}
cur++;
bool is_long = (*cur == 'l');
cur += is_long;
bool is_llong = (*cur == 'l');
cur += is_llong;
switch (*cur) {
case 'd': {
i64 v = is_llong ? va_arg(args, i64)
: is_long ? va_arg(args, iptr)
: va_arg(args, int);
result += AppendSignedDecimal(&buff, buff_end, v);
break;
}
case 'u':
case 'x': {
u64 v = is_llong ? va_arg(args, u64)
: is_long ? va_arg(args, uptr)
: va_arg(args, unsigned);
result += AppendUnsigned(&buff, buff_end, v, *cur == 'u' ? 10: 16, 0);
break;
}
case 'p': {
result += AppendPointer(&buff, buff_end, va_arg(args, uptr));
break;
}
case 's': {
result += AppendString(&buff, buff_end, va_arg(args, char*));
break;
}
default: {
Die();
}
}
}
AppendChar(&buff, buff_end + 1, '\0');
return result;
}
void TsanPrintf(const char *format, ...) { void TsanPrintf(const char *format, ...) {
ScopedInRtl in_rtl; ScopedInRtl in_rtl;
const uptr kMaxLen = 16 * 1024; const uptr kMaxLen = 16 * 1024;
@ -138,12 +36,4 @@ void TsanPrintf(const char *format, ...) {
buffer, len < buffer.Size() ? len : buffer.Size() - 1); buffer, len < buffer.Size() ? len : buffer.Size() - 1);
} }
uptr SNPrintf(char *buffer, uptr length, const char *format, ...) {
va_list args;
va_start(args, format);
uptr len = VSNPrintf(buffer, length, format, args);
va_end(args);
return len;
}
} // namespace __tsan } // namespace __tsan

View File

@ -70,10 +70,10 @@ static void PrintMop(const ReportMop *mop, bool first) {
static void PrintLocation(const ReportLocation *loc) { static void PrintLocation(const ReportLocation *loc) {
if (loc->type == ReportLocationGlobal) { if (loc->type == ReportLocationGlobal) {
TsanPrintf(" Location is global '%s' of size %lu at %lx %s:%d\n", TsanPrintf(" Location is global '%s' of size %zu at %zx %s:%d\n",
loc->name, loc->size, loc->addr, loc->file, loc->line); loc->name, loc->size, loc->addr, loc->file, loc->line);
} else if (loc->type == ReportLocationHeap) { } else if (loc->type == ReportLocationHeap) {
TsanPrintf(" Location is heap of size %lu at %lx allocated " TsanPrintf(" Location is heap of size %zu at %zx allocated "
"by thread %d:\n", loc->size, loc->addr, loc->tid); "by thread %d:\n", loc->size, loc->addr, loc->tid);
PrintStack(loc->stack); PrintStack(loc->stack);
} else if (loc->type == ReportLocationStack) { } else if (loc->type == ReportLocationStack) {

View File

@ -104,9 +104,9 @@ static void WriteMemoryProfile(char *buf, uptr buf_size, int num) {
uptr nsync = 0; uptr nsync = 0;
uptr syncmem = CTX()->synctab.GetMemoryConsumption(&nsync); uptr syncmem = CTX()->synctab.GetMemoryConsumption(&nsync);
SNPrintf(buf, buf_size, "%d: shadow=%luMB" SNPrintf(buf, buf_size, "%d: shadow=%zuMB"
" thread=%luMB(total=%d/live=%d)" " thread=%zuMB(total=%d/live=%d)"
" sync=%luMB(cnt=%lu)\n", " sync=%zuMB(cnt=%zu)\n",
num, num,
shadow >> 20, shadow >> 20,
threadmem >> 20, nthread, nlivethread, threadmem >> 20, nthread, nlivethread,
@ -359,17 +359,18 @@ void MemoryAccess(ThreadState *thr, uptr pc, uptr addr,
int kAccessSizeLog, bool kAccessIsWrite) { int kAccessSizeLog, bool kAccessIsWrite) {
u64 *shadow_mem = (u64*)MemToShadow(addr); u64 *shadow_mem = (u64*)MemToShadow(addr);
DPrintf2("#%d: tsan::OnMemoryAccess: @%p %p size=%d" DPrintf2("#%d: tsan::OnMemoryAccess: @%p %p size=%d"
" is_write=%d shadow_mem=%p {%llx, %llx, %llx, %llx}\n", " is_write=%d shadow_mem=%p {%zx, %zx, %zx, %zx}\n",
(int)thr->fast_state.tid(), (void*)pc, (void*)addr, (int)thr->fast_state.tid(), (void*)pc, (void*)addr,
(int)(1 << kAccessSizeLog), kAccessIsWrite, shadow_mem, (int)(1 << kAccessSizeLog), kAccessIsWrite, shadow_mem,
shadow_mem[0], shadow_mem[1], shadow_mem[2], shadow_mem[3]); (uptr)shadow_mem[0], (uptr)shadow_mem[1],
(uptr)shadow_mem[2], (uptr)shadow_mem[3]);
#if TSAN_DEBUG #if TSAN_DEBUG
if (!IsAppMem(addr)) { if (!IsAppMem(addr)) {
TsanPrintf("Access to non app mem %lx\n", addr); TsanPrintf("Access to non app mem %zx\n", addr);
DCHECK(IsAppMem(addr)); DCHECK(IsAppMem(addr));
} }
if (!IsShadowMem((uptr)shadow_mem)) { if (!IsShadowMem((uptr)shadow_mem)) {
TsanPrintf("Bad shadow addr %p (%lx)\n", shadow_mem, addr); TsanPrintf("Bad shadow addr %p (%zx)\n", shadow_mem, addr);
DCHECK(IsShadowMem((uptr)shadow_mem)); DCHECK(IsShadowMem((uptr)shadow_mem));
} }
#endif #endif

View File

@ -38,7 +38,6 @@
namespace __tsan { namespace __tsan {
void TsanPrintf(const char *format, ...) FORMAT(1, 2); void TsanPrintf(const char *format, ...) FORMAT(1, 2);
uptr SNPrintf(char *buffer, uptr length, const char *format, ...) FORMAT(3, 4);
// FastState (from most significant bit): // FastState (from most significant bit):
// unused : 1 // unused : 1

View File

@ -22,7 +22,7 @@ void MutexCreate(ThreadState *thr, uptr pc, uptr addr,
bool rw, bool recursive) { bool rw, bool recursive) {
Context *ctx = CTX(); Context *ctx = CTX();
CHECK_GT(thr->in_rtl, 0); CHECK_GT(thr->in_rtl, 0);
DPrintf("#%d: MutexCreate %lx\n", thr->tid, addr); DPrintf("#%d: MutexCreate %zx\n", thr->tid, addr);
StatInc(thr, StatMutexCreate); StatInc(thr, StatMutexCreate);
MemoryWrite1Byte(thr, pc, addr); MemoryWrite1Byte(thr, pc, addr);
SyncVar *s = ctx->synctab.GetAndLock(thr, pc, addr, true); SyncVar *s = ctx->synctab.GetAndLock(thr, pc, addr, true);
@ -34,7 +34,7 @@ void MutexCreate(ThreadState *thr, uptr pc, uptr addr,
void MutexDestroy(ThreadState *thr, uptr pc, uptr addr) { void MutexDestroy(ThreadState *thr, uptr pc, uptr addr) {
Context *ctx = CTX(); Context *ctx = CTX();
CHECK_GT(thr->in_rtl, 0); CHECK_GT(thr->in_rtl, 0);
DPrintf("#%d: MutexDestroy %lx\n", thr->tid, addr); DPrintf("#%d: MutexDestroy %zx\n", thr->tid, addr);
StatInc(thr, StatMutexDestroy); StatInc(thr, StatMutexDestroy);
MemoryWrite1Byte(thr, pc, addr); MemoryWrite1Byte(thr, pc, addr);
SyncVar *s = ctx->synctab.GetAndRemove(thr, pc, addr); SyncVar *s = ctx->synctab.GetAndRemove(thr, pc, addr);
@ -52,7 +52,7 @@ void MutexDestroy(ThreadState *thr, uptr pc, uptr addr) {
void MutexLock(ThreadState *thr, uptr pc, uptr addr) { void MutexLock(ThreadState *thr, uptr pc, uptr addr) {
CHECK_GT(thr->in_rtl, 0); CHECK_GT(thr->in_rtl, 0);
DPrintf("#%d: MutexLock %lx\n", thr->tid, addr); DPrintf("#%d: MutexLock %zx\n", thr->tid, addr);
MemoryRead1Byte(thr, pc, addr); MemoryRead1Byte(thr, pc, addr);
thr->fast_state.IncrementEpoch(); thr->fast_state.IncrementEpoch();
TraceAddEvent(thr, thr->fast_state.epoch(), EventTypeLock, addr); TraceAddEvent(thr, thr->fast_state.epoch(), EventTypeLock, addr);
@ -81,7 +81,7 @@ void MutexLock(ThreadState *thr, uptr pc, uptr addr) {
void MutexUnlock(ThreadState *thr, uptr pc, uptr addr) { void MutexUnlock(ThreadState *thr, uptr pc, uptr addr) {
CHECK_GT(thr->in_rtl, 0); CHECK_GT(thr->in_rtl, 0);
DPrintf("#%d: MutexUnlock %lx\n", thr->tid, addr); DPrintf("#%d: MutexUnlock %zx\n", thr->tid, addr);
MemoryRead1Byte(thr, pc, addr); MemoryRead1Byte(thr, pc, addr);
thr->fast_state.IncrementEpoch(); thr->fast_state.IncrementEpoch();
TraceAddEvent(thr, thr->fast_state.epoch(), EventTypeUnlock, addr); TraceAddEvent(thr, thr->fast_state.epoch(), EventTypeUnlock, addr);
@ -114,7 +114,7 @@ void MutexUnlock(ThreadState *thr, uptr pc, uptr addr) {
void MutexReadLock(ThreadState *thr, uptr pc, uptr addr) { void MutexReadLock(ThreadState *thr, uptr pc, uptr addr) {
CHECK_GT(thr->in_rtl, 0); CHECK_GT(thr->in_rtl, 0);
DPrintf("#%d: MutexReadLock %lx\n", thr->tid, addr); DPrintf("#%d: MutexReadLock %zx\n", thr->tid, addr);
StatInc(thr, StatMutexReadLock); StatInc(thr, StatMutexReadLock);
MemoryRead1Byte(thr, pc, addr); MemoryRead1Byte(thr, pc, addr);
thr->fast_state.IncrementEpoch(); thr->fast_state.IncrementEpoch();
@ -130,7 +130,7 @@ void MutexReadLock(ThreadState *thr, uptr pc, uptr addr) {
void MutexReadUnlock(ThreadState *thr, uptr pc, uptr addr) { void MutexReadUnlock(ThreadState *thr, uptr pc, uptr addr) {
CHECK_GT(thr->in_rtl, 0); CHECK_GT(thr->in_rtl, 0);
DPrintf("#%d: MutexReadUnlock %lx\n", thr->tid, addr); DPrintf("#%d: MutexReadUnlock %zx\n", thr->tid, addr);
StatInc(thr, StatMutexReadUnlock); StatInc(thr, StatMutexReadUnlock);
MemoryRead1Byte(thr, pc, addr); MemoryRead1Byte(thr, pc, addr);
thr->fast_state.IncrementEpoch(); thr->fast_state.IncrementEpoch();
@ -148,7 +148,7 @@ void MutexReadUnlock(ThreadState *thr, uptr pc, uptr addr) {
void MutexReadOrWriteUnlock(ThreadState *thr, uptr pc, uptr addr) { void MutexReadOrWriteUnlock(ThreadState *thr, uptr pc, uptr addr) {
CHECK_GT(thr->in_rtl, 0); CHECK_GT(thr->in_rtl, 0);
DPrintf("#%d: MutexReadOrWriteUnlock %lx\n", thr->tid, addr); DPrintf("#%d: MutexReadOrWriteUnlock %zx\n", thr->tid, addr);
MemoryRead1Byte(thr, pc, addr); MemoryRead1Byte(thr, pc, addr);
SyncVar *s = CTX()->synctab.GetAndLock(thr, pc, addr, true); SyncVar *s = CTX()->synctab.GetAndLock(thr, pc, addr, true);
if (s->owner_tid == SyncVar::kInvalidTid) { if (s->owner_tid == SyncVar::kInvalidTid) {
@ -189,7 +189,7 @@ void MutexReadOrWriteUnlock(ThreadState *thr, uptr pc, uptr addr) {
void Acquire(ThreadState *thr, uptr pc, uptr addr) { void Acquire(ThreadState *thr, uptr pc, uptr addr) {
CHECK_GT(thr->in_rtl, 0); CHECK_GT(thr->in_rtl, 0);
DPrintf("#%d: Acquire %lx\n", thr->tid, addr); DPrintf("#%d: Acquire %zx\n", thr->tid, addr);
SyncVar *s = CTX()->synctab.GetAndLock(thr, pc, addr, false); SyncVar *s = CTX()->synctab.GetAndLock(thr, pc, addr, false);
thr->clock.set(thr->tid, thr->fast_state.epoch()); thr->clock.set(thr->tid, thr->fast_state.epoch());
thr->clock.acquire(&s->clock); thr->clock.acquire(&s->clock);
@ -199,7 +199,7 @@ void Acquire(ThreadState *thr, uptr pc, uptr addr) {
void Release(ThreadState *thr, uptr pc, uptr addr) { void Release(ThreadState *thr, uptr pc, uptr addr) {
CHECK_GT(thr->in_rtl, 0); CHECK_GT(thr->in_rtl, 0);
DPrintf("#%d: Release %lx\n", thr->tid, addr); DPrintf("#%d: Release %zx\n", thr->tid, addr);
SyncVar *s = CTX()->synctab.GetAndLock(thr, pc, addr, true); SyncVar *s = CTX()->synctab.GetAndLock(thr, pc, addr, true);
thr->clock.set(thr->tid, thr->fast_state.epoch()); thr->clock.set(thr->tid, thr->fast_state.epoch());
thr->clock.release(&s->clock); thr->clock.release(&s->clock);

View File

@ -68,7 +68,7 @@ static void StackStripMain(ReportStack *stack) {
// can actually happen if we do not instrument some code, // can actually happen if we do not instrument some code,
// so it's only a DCHECK. However we must try hard to not miss it // so it's only a DCHECK. However we must try hard to not miss it
// due to our fault. // due to our fault.
TsanPrintf("Bottom stack frame of stack %lx is missed\n", stack->pc); TsanPrintf("Bottom stack frame of stack %zx is missed\n", stack->pc);
} }
} }
@ -189,19 +189,19 @@ static void RestoreStack(int tid, const u64 epoch, StackTrace *stk) {
return; return;
const u64 eend = epoch % kTraceSize; const u64 eend = epoch % kTraceSize;
const u64 ebegin = eend / kTracePartSize * kTracePartSize; const u64 ebegin = eend / kTracePartSize * kTracePartSize;
DPrintf("#%d: RestoreStack epoch=%llu ebegin=%llu eend=%llu partidx=%d\n", DPrintf("#%d: RestoreStack epoch=%zu ebegin=%zu eend=%zu partidx=%d\n",
tid, epoch, ebegin, eend, partidx); tid, (uptr)epoch, (uptr)ebegin, (uptr)eend, partidx);
InternalScopedBuf<uptr> stack(1024); // FIXME: de-hardcode 1024 InternalScopedBuf<uptr> stack(1024); // FIXME: de-hardcode 1024
for (uptr i = 0; i < hdr->stack0.Size(); i++) { for (uptr i = 0; i < hdr->stack0.Size(); i++) {
stack[i] = hdr->stack0.Get(i); stack[i] = hdr->stack0.Get(i);
DPrintf2(" #%02lu: pc=%lx\n", i, stack[i]); DPrintf2(" #%02lu: pc=%zx\n", i, stack[i]);
} }
uptr pos = hdr->stack0.Size(); uptr pos = hdr->stack0.Size();
for (uptr i = ebegin; i <= eend; i++) { for (uptr i = ebegin; i <= eend; i++) {
Event ev = trace->events[i]; Event ev = trace->events[i];
EventType typ = (EventType)(ev >> 61); EventType typ = (EventType)(ev >> 61);
uptr pc = (uptr)(ev & 0xffffffffffffull); uptr pc = (uptr)(ev & 0xffffffffffffull);
DPrintf2(" %lu typ=%d pc=%lx\n", i, typ, pc); DPrintf2(" %zu typ=%d pc=%zx\n", i, typ, pc);
if (typ == EventTypeMop) { if (typ == EventTypeMop) {
stack[pos] = pc; stack[pos] = pc;
} else if (typ == EventTypeFuncEnter) { } else if (typ == EventTypeFuncEnter) {
@ -213,7 +213,7 @@ static void RestoreStack(int tid, const u64 epoch, StackTrace *stk) {
pos--; pos--;
} }
for (uptr j = 0; j <= pos; j++) for (uptr j = 0; j <= pos; j++)
DPrintf2(" #%lu: %lx\n", j, stack[j]); DPrintf2(" #%zu: %zx\n", j, stack[j]);
} }
if (pos == 0 && stack[0] == 0) if (pos == 0 && stack[0] == 0)
return; return;
@ -349,8 +349,8 @@ void ReportRace(ThreadState *thr) {
void CheckFailed(const char *file, int line, const char *cond, u64 v1, u64 v2) { void CheckFailed(const char *file, int line, const char *cond, u64 v1, u64 v2) {
ScopedInRtl in_rtl; ScopedInRtl in_rtl;
TsanPrintf("FATAL: ThreadSanitizer CHECK failed: %s:%d \"%s\" (%llx, %llx)\n", TsanPrintf("FATAL: ThreadSanitizer CHECK failed: %s:%d \"%s\" (%zx, %zx)\n",
file, line, cond, v1, v2); file, line, cond, (uptr)v1, (uptr)v2);
Die(); Die();
} }

View File

@ -53,7 +53,7 @@ static void ThreadDead(ThreadState *thr, ThreadContext *tctx) {
CHECK_GT(thr->in_rtl, 0); CHECK_GT(thr->in_rtl, 0);
CHECK(tctx->status == ThreadStatusRunning CHECK(tctx->status == ThreadStatusRunning
|| tctx->status == ThreadStatusFinished); || tctx->status == ThreadStatusFinished);
DPrintf("#%d: ThreadDead uid=%lu\n", thr->tid, tctx->user_id); DPrintf("#%d: ThreadDead uid=%zu\n", thr->tid, tctx->user_id);
tctx->status = ThreadStatusDead; tctx->status = ThreadStatusDead;
tctx->user_id = 0; tctx->user_id = 0;
tctx->sync.Reset(); tctx->sync.Reset();
@ -106,7 +106,7 @@ int ThreadCreate(ThreadState *thr, uptr pc, uptr uid, bool detached) {
CHECK_NE(tctx, 0); CHECK_NE(tctx, 0);
CHECK_GE(tid, 0); CHECK_GE(tid, 0);
CHECK_LT(tid, kMaxTid); CHECK_LT(tid, kMaxTid);
DPrintf("#%d: ThreadCreate tid=%d uid=%lu\n", thr->tid, tid, uid); DPrintf("#%d: ThreadCreate tid=%d uid=%zu\n", thr->tid, tid, uid);
CHECK_EQ(tctx->status, ThreadStatusInvalid); CHECK_EQ(tctx->status, ThreadStatusInvalid);
ctx->alive_threads++; ctx->alive_threads++;
if (ctx->max_alive_threads < ctx->alive_threads) { if (ctx->max_alive_threads < ctx->alive_threads) {
@ -170,9 +170,9 @@ void ThreadStart(ThreadState *thr, int tid) {
thr->clock.set(tid, tctx->epoch0); thr->clock.set(tid, tctx->epoch0);
thr->clock.acquire(&tctx->sync); thr->clock.acquire(&tctx->sync);
StatInc(thr, StatSyncAcquire); StatInc(thr, StatSyncAcquire);
DPrintf("#%d: ThreadStart epoch=%llu stk_addr=%lx stk_size=%lx " DPrintf("#%d: ThreadStart epoch=%zu stk_addr=%zx stk_size=%zx "
"tls_addr=%lx tls_size=%lx\n", "tls_addr=%zx tls_size=%zx\n",
tid, tctx->epoch0, stk_addr, stk_size, tls_addr, tls_size); tid, (uptr)tctx->epoch0, stk_addr, stk_size, tls_addr, tls_size);
} }
void ThreadFinish(ThreadState *thr) { void ThreadFinish(ThreadState *thr) {
@ -239,7 +239,7 @@ int ThreadTid(ThreadState *thr, uptr pc, uptr uid) {
break; break;
} }
} }
DPrintf("#%d: ThreadTid uid=%lu tid=%d\n", thr->tid, uid, res); DPrintf("#%d: ThreadTid uid=%zu tid=%d\n", thr->tid, uid, res);
return res; return res;
} }
@ -292,20 +292,20 @@ void MemoryAccessRange(ThreadState *thr, uptr pc, uptr addr,
#if TSAN_DEBUG #if TSAN_DEBUG
if (!IsAppMem(addr)) { if (!IsAppMem(addr)) {
TsanPrintf("Access to non app mem %lx\n", addr); TsanPrintf("Access to non app mem %zx\n", addr);
DCHECK(IsAppMem(addr)); DCHECK(IsAppMem(addr));
} }
if (!IsAppMem(addr + size - 1)) { if (!IsAppMem(addr + size - 1)) {
TsanPrintf("Access to non app mem %lx\n", addr + size - 1); TsanPrintf("Access to non app mem %zx\n", addr + size - 1);
DCHECK(IsAppMem(addr + size - 1)); DCHECK(IsAppMem(addr + size - 1));
} }
if (!IsShadowMem((uptr)shadow_mem)) { if (!IsShadowMem((uptr)shadow_mem)) {
TsanPrintf("Bad shadow addr %p (%lx)\n", shadow_mem, addr); TsanPrintf("Bad shadow addr %p (%zx)\n", shadow_mem, addr);
DCHECK(IsShadowMem((uptr)shadow_mem)); DCHECK(IsShadowMem((uptr)shadow_mem));
} }
if (!IsShadowMem((uptr)(shadow_mem + size * kShadowCnt / 8 - 1))) { if (!IsShadowMem((uptr)(shadow_mem + size * kShadowCnt / 8 - 1))) {
TsanPrintf("Bad shadow addr %p (%lx)\n", TsanPrintf("Bad shadow addr %p (%zx)\n",
shadow_mem + size * kShadowCnt / 8 - 1, addr + size - 1); shadow_mem + size * kShadowCnt / 8 - 1, addr + size - 1);
DCHECK(IsShadowMem((uptr)(shadow_mem + size * kShadowCnt / 8 - 1))); DCHECK(IsShadowMem((uptr)(shadow_mem + size * kShadowCnt / 8 - 1)));
} }
#endif #endif

View File

@ -243,7 +243,7 @@ void StatOutput(u64 *stat) {
TsanPrintf("Statistics:\n"); TsanPrintf("Statistics:\n");
for (int i = 0; i < StatCnt; i++) for (int i = 0; i < StatCnt; i++)
TsanPrintf("%s: %llu\n", name[i], stat[i]); TsanPrintf("%s: %zu\n", name[i], (uptr)stat[i]);
} }
} // namespace __tsan } // namespace __tsan

View File

@ -102,13 +102,14 @@ static int dl_iterate_phdr_cb(dl_phdr_info *info, size_t size, void *arg) {
m->base = (uptr)info->dlpi_addr; m->base = (uptr)info->dlpi_addr;
m->inp_fd = -1; m->inp_fd = -1;
m->out_fd = -1; m->out_fd = -1;
DPrintf("Module %s %lx\n", m->name, m->base); DPrintf("Module %s %zx\n", m->name, m->base);
for (int i = 0; i < info->dlpi_phnum; i++) { for (int i = 0; i < info->dlpi_phnum; i++) {
const Elf64_Phdr *s = &info->dlpi_phdr[i]; const Elf64_Phdr *s = &info->dlpi_phdr[i];
DPrintf(" Section p_type=%llx p_offset=%llx p_vaddr=%llx p_paddr=%llx" DPrintf(" Section p_type=%zx p_offset=%zx p_vaddr=%zx p_paddr=%zx"
" p_filesz=%llx p_memsz=%llx p_flags=%llx p_align=%llx\n", " p_filesz=%zx p_memsz=%zx p_flags=%zx p_align=%zx\n",
(u64)s->p_type, (u64)s->p_offset, (u64)s->p_vaddr, (u64)s->p_paddr, (uptr)s->p_type, (uptr)s->p_offset, (uptr)s->p_vaddr,
(u64)s->p_filesz, (u64)s->p_memsz, (u64)s->p_flags, (u64)s->p_align); (uptr)s->p_paddr, (uptr)s->p_filesz, (uptr)s->p_memsz,
(uptr)s->p_flags, (uptr)s->p_align);
if (s->p_type != PT_LOAD) if (s->p_type != PT_LOAD)
continue; continue;
SectionDesc *sec = (SectionDesc*)internal_alloc(MBlockReportStack, SectionDesc *sec = (SectionDesc*)internal_alloc(MBlockReportStack,
@ -118,7 +119,7 @@ static int dl_iterate_phdr_cb(dl_phdr_info *info, size_t size, void *arg) {
sec->end = sec->base + s->p_memsz; sec->end = sec->base + s->p_memsz;
sec->next = ctx->sections; sec->next = ctx->sections;
ctx->sections = sec; ctx->sections = sec;
DPrintf(" Section %lx-%lx\n", sec->base, sec->end); DPrintf(" Section %zx-%zx\n", sec->base, sec->end);
} }
return 0; return 0;
} }
@ -199,7 +200,7 @@ ReportStack *SymbolizeData(uptr addr) {
int res = 0; int res = 0;
InternalScopedBuf<char> cmd(1024); InternalScopedBuf<char> cmd(1024);
SNPrintf(cmd, cmd.Size(), SNPrintf(cmd, cmd.Size(),
"nm -alC %s|grep \"%lx\"|awk '{printf(\"%%s\\n%%s\", $3, $4)}' > tsan.tmp2", "nm -alC %s|grep \"%zx\"|awk '{printf(\"%%s\\n%%s\", $3, $4)}' > tsan.tmp2",
exe, (addr - base)); exe, (addr - base));
if (system(cmd)) if (system(cmd))
return 0; return 0;

View File

@ -23,8 +23,8 @@ static void TestThreadInfo(bool main) {
uptr tls_addr = 0; uptr tls_addr = 0;
uptr tls_size = 0; uptr tls_size = 0;
GetThreadStackAndTls(main, &stk_addr, &stk_size, &tls_addr, &tls_size); GetThreadStackAndTls(main, &stk_addr, &stk_size, &tls_addr, &tls_size);
// Printf("stk=%lx-%lx(%lu)\n", stk_addr, stk_addr + stk_size, stk_size); // Printf("stk=%zx-%zx(%zu)\n", stk_addr, stk_addr + stk_size, stk_size);
// Printf("tls=%lx-%lx(%lu)\n", tls_addr, tls_addr + tls_size, tls_size); // Printf("tls=%zx-%zx(%zu)\n", tls_addr, tls_addr + tls_size, tls_size);
int stack_var; int stack_var;
EXPECT_NE(stk_addr, (uptr)0); EXPECT_NE(stk_addr, (uptr)0);

View File

@ -21,13 +21,13 @@ namespace __tsan {
TEST(Printf, Basic) { TEST(Printf, Basic) {
char buf[1024]; char buf[1024];
uptr len = SNPrintf(buf, sizeof(buf), uptr len = SNPrintf(buf, sizeof(buf),
"a%db%ldc%lldd%ue%luf%llug%xh%lxq%llxw%pe%sr", "a%db%zdc%ue%zuf%xh%zxq%pe%sr",
(int)-1, (long)-2, (long long)-3, // NOLINT (int)-1, (long)-2, // NOLINT
(unsigned)-4, (unsigned long)5, (unsigned long long)6, // NOLINT (unsigned)-4, (unsigned long)5, // NOLINT
(unsigned)10, (unsigned long)11, (unsigned long long)12, // NOLINT (unsigned)10, (unsigned long)11, // NOLINT
(void*)0x123, "_string_"); (void*)0x123, "_string_");
EXPECT_EQ(len, strlen(buf)); EXPECT_EQ(len, strlen(buf));
EXPECT_EQ(0, strcmp(buf, "a-1b-2c-3d4294967292e5f6gahbqcw" EXPECT_EQ(0, strcmp(buf, "a-1b-2c4294967292e5fahbq"
"0x000000000123e_string_r")); "0x000000000123e_string_r"));
} }
@ -60,7 +60,7 @@ TEST(Printf, OverflowInt) {
TEST(Printf, OverflowUint) { TEST(Printf, OverflowUint) {
char buf[] = "123456789"; char buf[] = "123456789";
SNPrintf(buf, 4, "a%llx", (long long)0x123456789); // NOLINT SNPrintf(buf, 4, "a%zx", (unsigned long)0x123456789); // NOLINT
EXPECT_EQ(0, strcmp(buf, "a12")); EXPECT_EQ(0, strcmp(buf, "a12"));
EXPECT_EQ(buf[3], 0); EXPECT_EQ(buf[3], 0);
EXPECT_EQ(buf[4], '5'); EXPECT_EQ(buf[4], '5');
@ -96,14 +96,11 @@ static void TestMinMax(const char *fmt, T min, T max) {
TEST(Printf, MinMax) { TEST(Printf, MinMax) {
TestMinMax<int>("%d-%d", INT_MIN, INT_MAX); // NOLINT TestMinMax<int>("%d-%d", INT_MIN, INT_MAX); // NOLINT
TestMinMax<long>("%ld-%ld", LONG_MIN, LONG_MAX); // NOLINT TestMinMax<long>("%zd-%zd", LONG_MIN, LONG_MAX); // NOLINT
TestMinMax<long long>("%lld-%lld", LLONG_MIN, LLONG_MAX); // NOLINT
TestMinMax<unsigned>("%u-%u", 0, UINT_MAX); // NOLINT TestMinMax<unsigned>("%u-%u", 0, UINT_MAX); // NOLINT
TestMinMax<unsigned long>("%lu-%lu", 0, ULONG_MAX); // NOLINT TestMinMax<unsigned long>("%zu-%zu", 0, ULONG_MAX); // NOLINT
TestMinMax<unsigned long long>("%llu-%llu", 0, ULLONG_MAX); // NOLINT
TestMinMax<unsigned>("%x-%x", 0, UINT_MAX); // NOLINT TestMinMax<unsigned>("%x-%x", 0, UINT_MAX); // NOLINT
TestMinMax<unsigned long>("%lx-%lx", 0, ULONG_MAX); // NOLINT TestMinMax<unsigned long>("%zx-%zx", 0, ULONG_MAX); // NOLINT
TestMinMax<unsigned long long>("%llx-%llx", 0, ULLONG_MAX); // NOLINT
} }
} // namespace __tsan } // namespace __tsan