forked from OSchip/llvm-project
[asan] add some colors to asan output if printing to tty (following ubsan)
llvm-svn: 170418
This commit is contained in:
parent
6d315cbcc3
commit
bad01549b6
|
@ -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);
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue