diff options
author | Kostya Serebryany <kcc@google.com> | 2012-12-18 07:32:16 +0000 |
---|---|---|
committer | Kostya Serebryany <kcc@google.com> | 2012-12-18 07:32:16 +0000 |
commit | 58f54555c2528f863e211a0679c2c423cfa55fb2 (patch) | |
tree | 18391fe4eaee237fc2bf939bebe7ce56f4e1009b | |
parent | c2234cd922bbd94e276e0bebb08004d63cbc5cf2 (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.cc | 77 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_report_decorator.h | 37 |
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 |