summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKostya Serebryany <kcc@google.com>2012-12-18 07:32:16 +0000
committerKostya Serebryany <kcc@google.com>2012-12-18 07:32:16 +0000
commit58f54555c2528f863e211a0679c2c423cfa55fb2 (patch)
tree18391fe4eaee237fc2bf939bebe7ce56f4e1009b
parentc2234cd922bbd94e276e0bebb08004d63cbc5cf2 (diff)
[asan] add some colors to asan output if printing to tty (following ubsan)
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@170418 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/asan/asan_report.cc77
-rw-r--r--lib/sanitizer_common/sanitizer_report_decorator.h37
2 files changed, 102 insertions, 12 deletions
diff --git a/lib/asan/asan_report.cc b/lib/asan/asan_report.cc
index 5ad911565..168957d21 100644
--- a/lib/asan/asan_report.cc
+++ b/lib/asan/asan_report.cc
@@ -18,6 +18,8 @@
#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 {
@@ -40,6 +42,20 @@ void AppendToErrorMessageBuffer(const char *buffer) {
}
}
+// ---------------------- 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) {
@@ -100,6 +116,8 @@ static void PrintGlobalNameIfASCII(const __asan_global &g) {
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);
@@ -110,6 +128,7 @@ bool DescribeAddressRelativeToGlobal(uptr addr, const __asan_global &g) {
}
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;
}
@@ -153,9 +172,12 @@ bool DescribeAddressIfStack(uptr addr, uptr access_size) {
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);
@@ -189,6 +211,8 @@ bool DescribeAddressIfStack(uptr addr, uptr access_size) {
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);
@@ -201,6 +225,7 @@ static void DescribeAccessToHeapChunk(AsanChunkView chunk, uptr addr,
}
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.
@@ -234,24 +259,30 @@ void DescribeHeapAddress(uptr addr, uptr access_size) {
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);
@@ -353,10 +384,13 @@ class ScopedInErrorReport {
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);
@@ -364,33 +398,45 @@ void ReportSIGSEGV(uptr pc, uptr sp, uptr bp, uptr addr) {
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);
}
@@ -399,9 +445,12 @@ void ReportStringFunctionMemoryRangesOverlap(
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);
@@ -494,17 +543,21 @@ void __asan_report_error(uptr pc, uptr bp, uptr sp,
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);
diff --git a/lib/sanitizer_common/sanitizer_report_decorator.h b/lib/sanitizer_common/sanitizer_report_decorator.h
new file mode 100644
index 000000000..50a3ee572
--- /dev/null
+++ b/lib/sanitizer_common/sanitizer_report_decorator.h
@@ -0,0 +1,37 @@
+//===-- sanitizer_report_decorator.h ----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Tags to decorate the sanitizer reports.
+// Currently supported tags:
+// * None.
+// * ANSI color sequences.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SANITIZER_ALLOCATOR_H
+#define SANITIZER_ALLOCATOR_H
+
+namespace __sanitizer {
+class AnsiColorDecorator {
+ public:
+ explicit AnsiColorDecorator(bool use_ansi_colors) : ansi_(use_ansi_colors) { }
+ const char *Black() { return ansi_ ? "\033[1m\033[30m" : ""; }
+ const char *Red() { return ansi_ ? "\033[1m\033[31m" : ""; }
+ const char *Green() { return ansi_ ? "\033[1m\033[32m" : ""; }
+ const char *Yellow() { return ansi_ ? "\033[1m\033[33m" : ""; }
+ const char *Blue() { return ansi_ ? "\033[1m\033[34m" : ""; }
+ const char *Magenta() { return ansi_ ? "\033[1m\033[35m" : ""; }
+ const char *Cyan() { return ansi_ ? "\033[1m\033[36m" : ""; }
+ const char *White() { return ansi_ ? "\033[1m\033[37m" : ""; }
+ const char *Default() { return ansi_ ? "\033[1m\033[0m" : ""; }
+ private:
+ bool ansi_;
+};
+} // namespace __sanitizer
+#endif // SANITIZER_ALLOCATOR_H