#include "asan_stack.h"
#include "asan_thread.h"
#include "asan_thread_registry.h"
+#include "sanitizer_common/sanitizer_common.h"
+#include "sanitizer_common/sanitizer_report_decorator.h"
namespace __asan {
}
}
+// ---------------------- Decorator ------------------------------ {{{1
+class Decorator: private __sanitizer::AnsiColorDecorator {
+ public:
+ Decorator() : __sanitizer::AnsiColorDecorator(PrintsToTty()) { }
+ const char *Warning() { return Red(); }
+ const char *EndWarning() { return Default(); }
+ const char *Access() { return Blue(); }
+ const char *EndAccess() { return Default(); }
+ const char *Location() { return Green(); }
+ const char *EndLocation() { return Default(); }
+ const char *Allocation() { return Magenta(); }
+ const char *EndAllocation() { return Default(); }
+};
+
// ---------------------- Helper functions ----------------------- {{{1
static void PrintBytes(const char *before, uptr *a) {
bool DescribeAddressRelativeToGlobal(uptr addr, const __asan_global &g) {
if (addr < g.beg - kGlobalAndStackRedzone) return false;
if (addr >= g.beg + g.size_with_redzone) return false;
+ Decorator d;
+ Printf("%s", d.Location());
Printf("%p is located ", (void*)addr);
if (addr < g.beg) {
Printf("%zd bytes to the left", g.beg - addr);
}
Printf(" of global variable '%s' (0x%zx) of size %zu\n",
g.name, g.beg, g.size);
+ Printf("%s", d.EndLocation());
PrintGlobalNameIfASCII(g);
return true;
}
internal_strncat(buf, frame_descr,
Min(kBufSize,
static_cast<sptr>(name_end - frame_descr)));
+ Decorator d;
+ Printf("%s", d.Location());
Printf("Address %p is located at offset %zu "
"in frame <%s> of T%d's stack:\n",
(void*)addr, offset, buf, t->tid());
+ Printf("%s", d.EndLocation());
// Report the number of stack objects.
char *p;
uptr n_objects = internal_simple_strtoll(name_end, &p, 10);
static void DescribeAccessToHeapChunk(AsanChunkView chunk, uptr addr,
uptr access_size) {
uptr offset;
+ Decorator d;
+ Printf("%s", d.Location());
Printf("%p is located ", (void*)addr);
if (chunk.AddrIsInside(addr, access_size, &offset)) {
Printf("%zu bytes inside of", offset);
}
Printf(" %zu-byte region [%p,%p)\n", chunk.UsedSize(),
(void*)(chunk.Beg()), (void*)(chunk.End()));
+ Printf("%s", d.EndLocation());
}
// Return " (thread_name) " or an empty string if the name is empty.
AsanThread *t = asanThreadRegistry().GetCurrent();
CHECK(t);
char tname[128];
+ Decorator d;
if (chunk.FreeTid() != kInvalidTid) {
AsanThreadSummary *free_thread =
asanThreadRegistry().FindByTid(chunk.FreeTid());
- Printf("freed by thread T%d%s here:\n", free_thread->tid(),
- ThreadNameWithParenthesis(free_thread, tname, sizeof(tname)));
+ Printf("%sfreed by thread T%d%s here:%s\n", d.Allocation(),
+ free_thread->tid(),
+ ThreadNameWithParenthesis(free_thread, tname, sizeof(tname)),
+ d.EndAllocation());
StackTrace free_stack;
chunk.GetFreeStack(&free_stack);
PrintStack(&free_stack);
- Printf("previously allocated by thread T%d%s here:\n",
- alloc_thread->tid(),
- ThreadNameWithParenthesis(alloc_thread, tname, sizeof(tname)));
+ Printf("%spreviously allocated by thread T%d%s here:%s\n",
+ d.Allocation(), alloc_thread->tid(),
+ ThreadNameWithParenthesis(alloc_thread, tname, sizeof(tname)),
+ d.EndAllocation());
PrintStack(&alloc_stack);
DescribeThread(t->summary());
DescribeThread(free_thread);
DescribeThread(alloc_thread);
} else {
- Printf("allocated by thread T%d%s here:\n", alloc_thread->tid(),
- ThreadNameWithParenthesis(alloc_thread, tname, sizeof(tname)));
+ Printf("%sallocated by thread T%d%s here:%s\n", d.Allocation(),
+ alloc_thread->tid(),
+ ThreadNameWithParenthesis(alloc_thread, tname, sizeof(tname)),
+ d.EndAllocation());
PrintStack(&alloc_stack);
DescribeThread(t->summary());
DescribeThread(alloc_thread);
void ReportSIGSEGV(uptr pc, uptr sp, uptr bp, uptr addr) {
ScopedInErrorReport in_report;
+ Decorator d;
+ Printf("%s", d.Warning());
Report("ERROR: AddressSanitizer: SEGV on unknown address %p"
" (pc %p sp %p bp %p T%d)\n",
(void*)addr, (void*)pc, (void*)sp, (void*)bp,
asanThreadRegistry().GetCurrentTidOrInvalid());
+ Printf("%s", d.EndWarning());
Printf("AddressSanitizer can not provide additional info.\n");
GET_STACK_TRACE_FATAL(pc, bp);
PrintStack(&stack);
void ReportDoubleFree(uptr addr, StackTrace *stack) {
ScopedInErrorReport in_report;
+ Decorator d;
+ Printf("%s", d.Warning());
Report("ERROR: AddressSanitizer: attempting double-free on %p:\n", addr);
+ Printf("%s", d.EndWarning());
PrintStack(stack);
DescribeHeapAddress(addr, 1);
}
void ReportFreeNotMalloced(uptr addr, StackTrace *stack) {
ScopedInErrorReport in_report;
+ Decorator d;
+ Printf("%s", d.Warning());
Report("ERROR: AddressSanitizer: attempting free on address "
"which was not malloc()-ed: %p\n", addr);
+ Printf("%s", d.EndWarning());
PrintStack(stack);
DescribeHeapAddress(addr, 1);
}
void ReportMallocUsableSizeNotOwned(uptr addr, StackTrace *stack) {
ScopedInErrorReport in_report;
+ Decorator d;
+ Printf("%s", d.Warning());
Report("ERROR: AddressSanitizer: attempting to call "
"malloc_usable_size() for pointer which is "
"not owned: %p\n", addr);
+ Printf("%s", d.EndWarning());
PrintStack(stack);
DescribeHeapAddress(addr, 1);
}
void ReportAsanGetAllocatedSizeNotOwned(uptr addr, StackTrace *stack) {
ScopedInErrorReport in_report;
+ Decorator d;
+ Printf("%s", d.Warning());
Report("ERROR: AddressSanitizer: attempting to call "
"__asan_get_allocated_size() for pointer which is "
"not owned: %p\n", addr);
+ Printf("%s", d.EndWarning());
PrintStack(stack);
DescribeHeapAddress(addr, 1);
}
const char *function, const char *offset1, uptr length1,
const char *offset2, uptr length2, StackTrace *stack) {
ScopedInErrorReport in_report;
+ Decorator d;
+ Printf("%s", d.Warning());
Report("ERROR: AddressSanitizer: %s-param-overlap: "
"memory ranges [%p,%p) and [%p, %p) overlap\n", \
function, offset1, offset1 + length1, offset2, offset2 + length2);
+ Printf("%s", d.EndWarning());
PrintStack(stack);
DescribeAddress((uptr)offset1, length1);
DescribeAddress((uptr)offset2, length2);
break;
}
}
-
+ Decorator d;
+ Printf("%s", d.Warning());
Report("ERROR: AddressSanitizer: %s on address "
"%p at pc 0x%zx bp 0x%zx sp 0x%zx\n",
bug_descr, (void*)addr, pc, bp, sp);
+ Printf("%s", d.EndWarning());
u32 curr_tid = asanThreadRegistry().GetCurrentTidOrInvalid();
char tname[128];
- Printf("%s of size %zu at %p thread T%d%s\n",
- access_size ? (is_write ? "WRITE" : "READ") : "ACCESS",
- access_size, (void*)addr, curr_tid,
- ThreadNameWithParenthesis(curr_tid, tname, sizeof(tname)));
+ Printf("%s%s of size %zu at %p thread T%d%s%s\n",
+ d.Access(),
+ access_size ? (is_write ? "WRITE" : "READ") : "ACCESS",
+ access_size, (void*)addr, curr_tid,
+ ThreadNameWithParenthesis(curr_tid, tname, sizeof(tname)),
+ d.EndAccess());
GET_STACK_TRACE_FATAL(pc, bp);
PrintStack(&stack);