[llvm-commits] [compiler-rt] r161666 - in /compiler-rt/trunk/lib/asan: asan_report.cc asan_report.h output_tests/null_deref.cc
Alexey Samsonov
samsonov at google.com
Fri Aug 10 08:13:05 PDT 2012
Author: samsonov
Date: Fri Aug 10 10:13:05 2012
New Revision: 161666
URL: http://llvm.org/viewvc/llvm-project?rev=161666&view=rev
Log:
[ASan] share code executed at the beginning/end of printing error reports
Modified:
compiler-rt/trunk/lib/asan/asan_report.cc
compiler-rt/trunk/lib/asan/asan_report.h
compiler-rt/trunk/lib/asan/output_tests/null_deref.cc
Modified: compiler-rt/trunk/lib/asan/asan_report.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_report.cc?rev=161666&r1=161665&r2=161666&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_report.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_report.cc Fri Aug 10 10:13:05 2012
@@ -11,6 +11,7 @@
//
// This file contains error reporting code.
//===----------------------------------------------------------------------===//
+#include "asan_flags.h"
#include "asan_internal.h"
#include "asan_mapping.h"
#include "asan_report.h"
@@ -39,10 +40,52 @@
}
}
+// ---------------------- Helper functions ----------------------- {{{1
+
+static void PrintBytes(const char *before, uptr *a) {
+ u8 *bytes = (u8*)a;
+ uptr byte_num = (__WORDSIZE) / 8;
+ AsanPrintf("%s%p:", before, (void*)a);
+ for (uptr i = 0; i < byte_num; i++) {
+ AsanPrintf(" %x%x", bytes[i] >> 4, bytes[i] & 15);
+ }
+ AsanPrintf("\n");
+}
+
+static void PrintShadowMemoryForAddress(uptr addr) {
+ if (!AddrIsInMem(addr))
+ return;
+ uptr shadow_addr = MemToShadow(addr);
+ AsanPrintf("Shadow byte and word:\n");
+ AsanPrintf(" %p: %x\n", (void*)shadow_addr, *(unsigned char*)shadow_addr);
+ uptr aligned_shadow = shadow_addr & ~(kWordSize - 1);
+ PrintBytes(" ", (uptr*)(aligned_shadow));
+ AsanPrintf("More shadow bytes:\n");
+ for (int i = -4; i <= 4; i++) {
+ const char *prefix = (i == 0) ? "=>" : " ";
+ PrintBytes(prefix, (uptr*)(aligned_shadow + i * kWordSize));
+ }
+}
+
+static void PrintZoneForPointer(uptr ptr, uptr zone_ptr,
+ const char *zone_name) {
+ if (zone_ptr) {
+ if (zone_name) {
+ AsanPrintf("malloc_zone_from_ptr(%p) = %p, which is %s\n",
+ ptr, zone_ptr, zone_name);
+ } else {
+ AsanPrintf("malloc_zone_from_ptr(%p) = %p, which doesn't have a name\n",
+ ptr, zone_ptr);
+ }
+ } else {
+ AsanPrintf("malloc_zone_from_ptr(%p) = 0\n", ptr);
+ }
+}
+
// ---------------------- Address Descriptions ------------------- {{{1
static bool IsASCII(unsigned char c) {
- return 0x00 <= c && c <= 0x7F;
+ return /*0x00 <= c &&*/ c <= 0x7F;
}
// Check if the global is a zero-terminated ASCII string. If so, print it.
@@ -158,113 +201,139 @@
// -------------------- Different kinds of reports ----------------- {{{1
+// Use ScopedInErrorReport to run common actions just before and
+// immediately after printing error report.
+class ScopedInErrorReport {
+ public:
+ ScopedInErrorReport() {
+ static atomic_uint32_t num_calls;
+ if (atomic_fetch_add(&num_calls, 1, memory_order_relaxed) != 0) {
+ // Do not print more than one report, otherwise they will mix up.
+ // Error reporting functions shouldn't return at this situation, as
+ // they are defined as no-return.
+ AsanReport("AddressSanitizer: while reporting a bug found another one."
+ "Ignoring.\n");
+ SleepForSeconds(Max(5, flags()->sleep_before_dying + 1));
+ // Try to prevent substituting infinite busy loop with _exit or smth
+ // like that.
+ volatile int x = 1;
+ while (x) { }
+ }
+ AsanPrintf("===================================================="
+ "=============\n");
+ AsanThread *curr_thread = asanThreadRegistry().GetCurrent();
+ if (curr_thread) {
+ // We started reporting an error message. Stop using the fake stack
+ // in case we call an instrumented function from a symbolizer.
+ curr_thread->fake_stack().StopUsingFakeStack();
+ }
+ }
+ // Destructor is NORETURN, as functions that report errors are.
+ NORETURN ~ScopedInErrorReport() {
+ // Make sure the current thread is announced.
+ AsanThread *curr_thread = asanThreadRegistry().GetCurrent();
+ if (curr_thread) {
+ curr_thread->summary()->Announce();
+ }
+ // Print memory stats.
+ __asan_print_accumulated_stats();
+ if (error_report_callback) {
+ error_report_callback(error_message_buffer);
+ }
+ AsanReport("ABORTING\n");
+ Die();
+ }
+};
+
void ReportSIGSEGV(uptr pc, uptr sp, uptr bp, uptr addr) {
+ ScopedInErrorReport in_report;
AsanReport("ERROR: AddressSanitizer crashed on unknown address %p"
" (pc %p sp %p bp %p T%d)\n",
(void*)addr, (void*)pc, (void*)sp, (void*)bp,
asanThreadRegistry().GetCurrentTidOrInvalid());
- AsanPrintf("AddressSanitizer can not provide additional info. ABORTING\n");
+ AsanPrintf("AddressSanitizer can not provide additional info.\n");
GET_STACK_TRACE_WITH_PC_AND_BP(kStackTraceMax, pc, bp);
stack.PrintStack();
- ShowStatsAndAbort();
}
void ReportDoubleFree(uptr addr, AsanStackTrace *stack) {
+ ScopedInErrorReport in_report;
AsanReport("ERROR: AddressSanitizer attempting double-free on %p:\n", addr);
stack->PrintStack();
DescribeHeapAddress(addr, 1);
- ShowStatsAndAbort();
}
void ReportFreeNotMalloced(uptr addr, AsanStackTrace *stack) {
+ ScopedInErrorReport in_report;
AsanReport("ERROR: AddressSanitizer attempting free on address "
"which was not malloc()-ed: %p\n", addr);
stack->PrintStack();
- ShowStatsAndAbort();
+ DescribeHeapAddress(addr, 1);
}
void ReportMallocUsableSizeNotOwned(uptr addr, AsanStackTrace *stack) {
+ ScopedInErrorReport in_report;
AsanReport("ERROR: AddressSanitizer attempting to call "
"malloc_usable_size() for pointer which is "
"not owned: %p\n", addr);
stack->PrintStack();
DescribeHeapAddress(addr, 1);
- ShowStatsAndAbort();
}
void ReportAsanGetAllocatedSizeNotOwned(uptr addr, AsanStackTrace *stack) {
+ ScopedInErrorReport in_report;
AsanReport("ERROR: AddressSanitizer attempting to call "
"__asan_get_allocated_size() for pointer which is "
"not owned: %p\n", addr);
stack->PrintStack();
DescribeHeapAddress(addr, 1);
- ShowStatsAndAbort();
}
void ReportStringFunctionMemoryRangesOverlap(
const char *function, const char *offset1, uptr length1,
const char *offset2, uptr length2, AsanStackTrace *stack) {
+ ScopedInErrorReport in_report;
AsanReport("ERROR: AddressSanitizer %s-param-overlap: "
"memory ranges [%p,%p) and [%p, %p) overlap\n", \
function, offset1, offset1 + length1, offset2, offset2 + length2);
stack->PrintStack();
- ShowStatsAndAbort();
+ DescribeAddress((uptr)offset1, length1);
+ DescribeAddress((uptr)offset2, length2);
}
// ----------------------- Mac-specific reports ----------------- {{{1
-static void PrintZoneForPointer(uptr ptr, uptr zone_ptr,
- const char *zone_name) {
- if (zone_ptr) {
- if (zone_name) {
- AsanPrintf("malloc_zone_from_ptr(%p) = %p, which is %s\n",
- ptr, zone_ptr, zone_name);
- } else {
- AsanPrintf("malloc_zone_from_ptr(%p) = %p, which doesn't have a name\n",
- ptr, zone_ptr);
- }
- } else {
- AsanPrintf("malloc_zone_from_ptr(%p) = 0\n", ptr);
- }
-}
-
void WarnMacFreeUnallocated(
uptr addr, uptr zone_ptr, const char *zone_name, AsanStackTrace *stack) {
+ // Just print a warning here.
AsanPrintf("free_common(%p) -- attempting to free unallocated memory.\n"
"AddressSanitizer is ignoring this error on Mac OS now.\n",
addr);
PrintZoneForPointer(addr, zone_ptr, zone_name);
stack->PrintStack();
+ DescribeHeapAddress(addr, 1);
}
void ReportMacMzReallocUnknown(
uptr addr, uptr zone_ptr, const char *zone_name, AsanStackTrace *stack) {
+ ScopedInErrorReport in_report;
AsanPrintf("mz_realloc(%p) -- attempting to realloc unallocated memory.\n"
"This is an unrecoverable problem, exiting now.\n",
addr);
PrintZoneForPointer(addr, zone_ptr, zone_name);
stack->PrintStack();
- ShowStatsAndAbort();
+ DescribeHeapAddress(addr, 1);
}
void ReportMacCfReallocUnknown(
uptr addr, uptr zone_ptr, const char *zone_name, AsanStackTrace *stack) {
+ ScopedInErrorReport in_report;
AsanPrintf("cf_realloc(%p) -- attempting to realloc unallocated memory.\n"
"This is an unrecoverable problem, exiting now.\n",
addr);
PrintZoneForPointer(addr, zone_ptr, zone_name);
stack->PrintStack();
- ShowStatsAndAbort();
-}
-
-static void PrintBytes(const char *before, uptr *a) {
- u8 *bytes = (u8*)a;
- uptr byte_num = (__WORDSIZE) / 8;
- AsanPrintf("%s%p:", before, (void*)a);
- for (uptr i = 0; i < byte_num; i++) {
- AsanPrintf(" %x%x", bytes[i] >> 4, bytes[i] & 15);
- }
- AsanPrintf("\n");
+ DescribeHeapAddress(addr, 1);
}
} // namespace __asan
@@ -274,18 +343,9 @@
void __asan_report_error(uptr pc, uptr bp, uptr sp,
uptr addr, bool is_write, uptr access_size) {
- static atomic_uint32_t num_calls;
- if (atomic_fetch_add(&num_calls, 1, memory_order_relaxed) != 0) {
- // Do not print more than one report, otherwise they will mix up.
- // We can not return here because the function is marked as never-return.
- AsanPrintf("AddressSanitizer: while reporting a bug found another one."
- "Ignoring.\n");
- SleepForSeconds(5);
- Die();
- }
+ ScopedInErrorReport in_report;
- AsanPrintf("===================================================="
- "=============\n");
+ // Determine the error type.
const char *bug_descr = "unknown-crash";
if (AddrIsInMem(addr)) {
u8 *shadow_addr = (u8*)MemToShadow(addr);
@@ -323,55 +383,21 @@
}
}
- AsanThread *curr_thread = asanThreadRegistry().GetCurrent();
- u32 curr_tid = asanThreadRegistry().GetCurrentTidOrInvalid();
-
- if (curr_thread) {
- // We started reporting an error message. Stop using the fake stack
- // in case we will call an instrumented function from a symbolizer.
- curr_thread->fake_stack().StopUsingFakeStack();
- }
-
AsanReport("ERROR: AddressSanitizer %s on address "
"%p at pc 0x%zx bp 0x%zx sp 0x%zx\n",
bug_descr, (void*)addr, pc, bp, sp);
+ u32 curr_tid = asanThreadRegistry().GetCurrentTidOrInvalid();
AsanPrintf("%s of size %zu at %p thread T%d\n",
access_size ? (is_write ? "WRITE" : "READ") : "ACCESS",
access_size, (void*)addr, curr_tid);
- if (flags()->debug) {
- PrintBytes("PC: ", (uptr*)pc);
- }
-
GET_STACK_TRACE_WITH_PC_AND_BP(kStackTraceMax, pc, bp);
stack.PrintStack();
DescribeAddress(addr, access_size);
- if (AddrIsInMem(addr)) {
- uptr shadow_addr = MemToShadow(addr);
- AsanReport("ABORTING\n");
- __asan_print_accumulated_stats();
- AsanPrintf("Shadow byte and word:\n");
- AsanPrintf(" %p: %x\n", (void*)shadow_addr, *(unsigned char*)shadow_addr);
- uptr aligned_shadow = shadow_addr & ~(kWordSize - 1);
- PrintBytes(" ", (uptr*)(aligned_shadow));
- AsanPrintf("More shadow bytes:\n");
- PrintBytes(" ", (uptr*)(aligned_shadow-4*kWordSize));
- PrintBytes(" ", (uptr*)(aligned_shadow-3*kWordSize));
- PrintBytes(" ", (uptr*)(aligned_shadow-2*kWordSize));
- PrintBytes(" ", (uptr*)(aligned_shadow-1*kWordSize));
- PrintBytes("=>", (uptr*)(aligned_shadow+0*kWordSize));
- PrintBytes(" ", (uptr*)(aligned_shadow+1*kWordSize));
- PrintBytes(" ", (uptr*)(aligned_shadow+2*kWordSize));
- PrintBytes(" ", (uptr*)(aligned_shadow+3*kWordSize));
- PrintBytes(" ", (uptr*)(aligned_shadow+4*kWordSize));
- }
- if (error_report_callback) {
- error_report_callback(error_message_buffer);
- }
- Die();
+ PrintShadowMemoryForAddress(addr);
}
void NOINLINE __asan_set_error_report_callback(void (*callback)(const char*)) {
Modified: compiler-rt/trunk/lib/asan/asan_report.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_report.h?rev=161666&r1=161665&r2=161666&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_report.h (original)
+++ compiler-rt/trunk/lib/asan/asan_report.h Fri Aug 10 10:13:05 2012
@@ -29,7 +29,6 @@
// Different kinds of error reports.
void NORETURN ReportSIGSEGV(uptr pc, uptr sp, uptr bp, uptr addr);
-
void NORETURN ReportDoubleFree(uptr addr, AsanStackTrace *stack);
void NORETURN ReportFreeNotMalloced(uptr addr, AsanStackTrace *stack);
void NORETURN ReportMallocUsableSizeNotOwned(uptr addr,
Modified: compiler-rt/trunk/lib/asan/output_tests/null_deref.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/output_tests/null_deref.cc?rev=161666&r1=161665&r2=161666&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/output_tests/null_deref.cc (original)
+++ compiler-rt/trunk/lib/asan/output_tests/null_deref.cc Fri Aug 10 10:13:05 2012
@@ -8,7 +8,7 @@
// Check-Common: {{.*ERROR: AddressSanitizer crashed on unknown address}}
// Check-Common: {{0x0*00028 .*pc 0x.*}}
-// Check-Common: {{AddressSanitizer can not provide additional info. ABORTING}}
+// Check-Common: {{AddressSanitizer can not provide additional info.}}
// atos on Mac cannot extract the symbol name correctly.
// Check-Linux: {{ #0 0x.* in NullDeref.*null_deref.cc:3}}
More information about the llvm-commits
mailing list