diff options
author | Kuba Brecka <kuba.brecka@gmail.com> | 2014-09-26 05:25:37 +0000 |
---|---|---|
committer | Kuba Brecka <kuba.brecka@gmail.com> | 2014-09-26 05:25:37 +0000 |
commit | 72983a82c3bc67afecb3550a63a495f758cff53d (patch) | |
tree | e108cd387585bbb04cce905b4e4547d83f20861d | |
parent | e5201f5d4f061d560cc5e100c1328081745d2e98 (diff) |
[compiler-rt] revert r218481 due to test failure on sanitizer-x86_64-linux
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@218501 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/sanitizer/asan_interface.h | 26 | ||||
-rw-r--r-- | lib/asan/asan_debugging.cc | 70 | ||||
-rw-r--r-- | lib/asan/asan_globals.cc | 42 | ||||
-rw-r--r-- | lib/asan/asan_interface_internal.h | 22 | ||||
-rw-r--r-- | lib/asan/asan_report.cc | 85 | ||||
-rw-r--r-- | lib/asan/asan_report.h | 13 | ||||
-rw-r--r-- | test/asan/TestCases/debug_locate.cc | 79 | ||||
-rw-r--r-- | test/asan/TestCases/debug_report.cc | 48 |
8 files changed, 24 insertions, 361 deletions
diff --git a/include/sanitizer/asan_interface.h b/include/sanitizer/asan_interface.h index 8ae434008..db0d1f5d3 100644 --- a/include/sanitizer/asan_interface.h +++ b/include/sanitizer/asan_interface.h @@ -62,32 +62,6 @@ extern "C" { // Print the description of addr (useful when debugging in gdb). void __asan_describe_address(void *addr); - // Useful for calling from a debugger to get information about an ASan error. - // Returns 1 if an error has been (or is being) reported, otherwise returns 0. - int __asan_report_present(); - - // Useful for calling from a debugger to get information about an ASan error. - // If an error has been (or is being) reported, the following functions return - // the pc, bp, sp, address, access type (0 = read, 1 = write), access size and - // bug description (e.g. "heap-use-after-free"). Otherwise they return 0. - void *__asan_get_report_pc(); - void *__asan_get_report_bp(); - void *__asan_get_report_sp(); - void *__asan_get_report_address(); - int __asan_get_report_access_type(); - size_t __asan_get_report_access_size(); - const char *__asan_get_report_description(); - - // Useful for calling from the debugger to get information about a pointer. - // Returns the category of the given pointer as a constant string. - // Possible return values are "global", "stack", "stack-fake", "heap", - // "heap-invalid", "shadow-low", "shadow-gap", "shadow-high", "unknown". - // If global or stack, tries to also return the variable name, address and - // size. If heap, tries to return the chunk address and size. 'name' should - // point to an allocated buffer of size 'name_size'. - const char *__asan_locate_address(void *addr, char *name, size_t name_size, - void **region_address, size_t *region_size); - // Useful for calling from the debugger to get the allocation stack trace // and thread ID for a heap address. Stores up to 'size' frames into 'trace', // returns the number of stored frames or 0 on error. diff --git a/lib/asan/asan_debugging.cc b/lib/asan/asan_debugging.cc index 2b41f6785..05198a787 100644 --- a/lib/asan/asan_debugging.cc +++ b/lib/asan/asan_debugging.cc @@ -17,70 +17,10 @@ #include "asan_flags.h" #include "asan_internal.h" #include "asan_mapping.h" -#include "asan_report.h" #include "asan_thread.h" namespace __asan { -void GetInfoForStackVar(uptr addr, AddressDescription *descr, AsanThread *t) { - descr->name[0] = 0; - descr->region_address = 0; - descr->region_size = 0; - descr->region_kind = "stack"; - - uptr offset = 0; - uptr frame_pc = 0; - const char *frame_descr = t->GetFrameNameByAddr(addr, &offset, &frame_pc); - InternalMmapVector<StackVarDescr> vars(16); - if (!ParseFrameDescription(frame_descr, &vars)) { - return; - } - - for (uptr i = 0; i < vars.size(); i++) { - if (offset <= vars[i].beg + vars[i].size) { - internal_strncat(descr->name, vars[i].name_pos, - Min(descr->name_size, vars[i].name_len)); - descr->region_address = addr - (offset - vars[i].beg); - descr->region_size = vars[i].size; - return; - } - } -} - -void GetInfoForHeapAddress(uptr addr, AddressDescription *descr) { - AsanChunkView chunk = FindHeapChunkByAddress(addr); - - descr->name[0] = 0; - descr->region_address = 0; - descr->region_size = 0; - - if (!chunk.IsValid()) { - descr->region_kind = "heap-invalid"; - return; - } - - descr->region_address = chunk.Beg(); - descr->region_size = chunk.UsedSize(); - descr->region_kind = "heap"; -} - -void AsanLocateAddress(uptr addr, AddressDescription *descr) { - if (DescribeAddressIfShadow(addr, descr, /* print */ false)) { - return; - } - if (GetInfoForAddressIfGlobal(addr, descr)) { - return; - } - asanThreadRegistry().Lock(); - AsanThread *thread = FindThreadByStackAddress(addr); - asanThreadRegistry().Unlock(); - if (thread) { - GetInfoForStackVar(addr, descr, thread); - return; - } - GetInfoForHeapAddress(addr, descr); -} - uptr AsanGetStack(uptr addr, uptr *trace, uptr size, u32 *thread_id, bool alloc_stack) { AsanChunkView chunk = FindHeapChunkByAddress(addr); @@ -116,16 +56,6 @@ uptr AsanGetStack(uptr addr, uptr *trace, uptr size, u32 *thread_id, using namespace __asan; SANITIZER_INTERFACE_ATTRIBUTE -const char *__asan_locate_address(uptr addr, char *name, uptr name_size, - uptr *region_address, uptr *region_size) { - AddressDescription descr = { name, name_size, 0, 0, 0 }; - AsanLocateAddress(addr, &descr); - if (region_address) *region_address = descr.region_address; - if (region_size) *region_size = descr.region_size; - return descr.region_kind; -} - -SANITIZER_INTERFACE_ATTRIBUTE uptr __asan_get_alloc_stack(uptr addr, uptr *trace, uptr size, u32 *thread_id) { return AsanGetStack(addr, trace, size, thread_id, /* alloc_stack */ true); } diff --git a/lib/asan/asan_globals.cc b/lib/asan/asan_globals.cc index b95064196..dc1cb4159 100644 --- a/lib/asan/asan_globals.cc +++ b/lib/asan/asan_globals.cc @@ -71,14 +71,6 @@ ALWAYS_INLINE void PoisonRedZones(const Global &g) { } } -const uptr kMinimalDistanceFromAnotherGlobal = 64; - -bool IsAddressNearGlobal(uptr addr, const __asan_global &g) { - if (addr <= g.beg - kMinimalDistanceFromAnotherGlobal) return false; - if (addr >= g.beg + g.size_with_redzone) return false; - return true; -} - static void ReportGlobal(const Global &g, const char *prefix) { Report("%s Global[%p]: beg=%p size=%zu/%zu name=%s module=%s dyn_init=%zu\n", prefix, &g, (void *)g.beg, g.size, g.size_with_redzone, g.name, @@ -90,45 +82,19 @@ static void ReportGlobal(const Global &g, const char *prefix) { } } -static bool DescribeOrGetInfoIfGlobal(uptr addr, uptr size, bool print, - Global *output_global) { +bool DescribeAddressIfGlobal(uptr addr, uptr size) { if (!flags()->report_globals) return false; BlockingMutexLock lock(&mu_for_globals); bool res = false; for (ListOfGlobals *l = list_of_all_globals; l; l = l->next) { const Global &g = *l->g; - if (print) { - if (flags()->report_globals >= 2) - ReportGlobal(g, "Search"); - res |= DescribeAddressRelativeToGlobal(addr, size, g); - } else { - if (IsAddressNearGlobal(addr, g)) { - CHECK(output_global); - *output_global = g; - return true; - } - } + if (flags()->report_globals >= 2) + ReportGlobal(g, "Search"); + res |= DescribeAddressRelativeToGlobal(addr, size, g); } return res; } -bool DescribeAddressIfGlobal(uptr addr, uptr size) { - return DescribeOrGetInfoIfGlobal(addr, size, /* print */ true, - /* output_global */ nullptr); -} - -bool GetInfoForAddressIfGlobal(uptr addr, AddressDescription *descr) { - Global g = {}; - if (DescribeOrGetInfoIfGlobal(addr, /* size */ 1, /* print */ false, &g)) { - internal_strncpy(descr->name, g.name, descr->name_size); - descr->region_address = g.beg; - descr->region_size = g.size; - descr->region_kind = "global"; - return true; - } - return false; -} - u32 FindRegistrationSite(const Global *g) { CHECK(global_registration_site_vector); for (uptr i = 0, n = global_registration_site_vector->size(); i < n; i++) { diff --git a/lib/asan/asan_interface_internal.h b/lib/asan/asan_interface_internal.h index a8399754a..33d7554b4 100644 --- a/lib/asan/asan_interface_internal.h +++ b/lib/asan/asan_interface_internal.h @@ -91,28 +91,6 @@ extern "C" { void __asan_describe_address(uptr addr); SANITIZER_INTERFACE_ATTRIBUTE - int __asan_report_present(); - - SANITIZER_INTERFACE_ATTRIBUTE - uptr __asan_get_report_pc(); - SANITIZER_INTERFACE_ATTRIBUTE - uptr __asan_get_report_bp(); - SANITIZER_INTERFACE_ATTRIBUTE - uptr __asan_get_report_sp(); - SANITIZER_INTERFACE_ATTRIBUTE - uptr __asan_get_report_address(); - SANITIZER_INTERFACE_ATTRIBUTE - int __asan_get_report_access_type(); - SANITIZER_INTERFACE_ATTRIBUTE - uptr __asan_get_report_access_size(); - SANITIZER_INTERFACE_ATTRIBUTE - const char * __asan_get_report_description(); - - SANITIZER_INTERFACE_ATTRIBUTE - const char * __asan_locate_address(uptr addr, char *name, uptr name_size, - uptr *region_address, uptr *region_size); - - SANITIZER_INTERFACE_ATTRIBUTE uptr __asan_get_alloc_stack(uptr addr, uptr *trace, uptr size, u32 *thread_id); diff --git a/lib/asan/asan_report.cc b/lib/asan/asan_report.cc index d77be3275..31d9c8de3 100644 --- a/lib/asan/asan_report.cc +++ b/lib/asan/asan_report.cc @@ -31,19 +31,6 @@ static char *error_message_buffer = 0; static uptr error_message_buffer_pos = 0; static uptr error_message_buffer_size = 0; -struct ReportData { - uptr pc; - uptr sp; - uptr bp; - uptr addr; - bool is_write; - uptr access_size; - const char *description; -}; - -static bool report_happened = false; -static ReportData report_data = {}; - void AppendToErrorMessageBuffer(const char *buffer) { if (error_message_buffer) { uptr length = internal_strlen(buffer); @@ -275,7 +262,9 @@ static void PrintGlobalLocation(InternalScopedString *str, bool DescribeAddressRelativeToGlobal(uptr addr, uptr size, const __asan_global &g) { - if (!IsAddressNearGlobal(addr, g)) return false; + static const uptr kMinimalDistanceFromAnotherGlobal = 64; + if (addr <= g.beg - kMinimalDistanceFromAnotherGlobal) return false; + if (addr >= g.beg + g.size_with_redzone) return false; InternalScopedString str(4096); Decorator d; str.append("%s", d.Location()); @@ -301,20 +290,21 @@ bool DescribeAddressRelativeToGlobal(uptr addr, uptr size, return true; } -bool DescribeAddressIfShadow(uptr addr, AddressDescription *descr, bool print) { +bool DescribeAddressIfShadow(uptr addr) { if (AddrIsInMem(addr)) return false; - const char *area_type = nullptr; - if (AddrIsInShadowGap(addr)) area_type = "shadow gap"; - else if (AddrIsInHighShadow(addr)) area_type = "high shadow"; - else if (AddrIsInLowShadow(addr)) area_type = "low shadow"; - if (area_type != nullptr) { - if (print) { - Printf("Address %p is located in the %s area.\n", addr, area_type); - } else { - CHECK(descr); - descr->region_kind = area_type; - } + static const char kAddrInShadowReport[] = + "Address %p is located in the %s.\n"; + if (AddrIsInShadowGap(addr)) { + Printf(kAddrInShadowReport, addr, "shadow gap area"); + return true; + } + if (AddrIsInHighShadow(addr)) { + Printf(kAddrInShadowReport, addr, "high shadow area"); + return true; + } + if (AddrIsInLowShadow(addr)) { + Printf(kAddrInShadowReport, addr, "low shadow area"); return true; } CHECK(0 && "Address is not in memory and not in shadow?"); @@ -592,7 +582,7 @@ void DescribeThread(AsanThreadContext *context) { // immediately after printing error report. class ScopedInErrorReport { public: - explicit ScopedInErrorReport(ReportData *report = nullptr) { + ScopedInErrorReport() { static atomic_uint32_t num_calls; static u32 reporting_thread_tid; if (atomic_fetch_add(&num_calls, 1, memory_order_relaxed) != 0) { @@ -612,8 +602,6 @@ class ScopedInErrorReport { // Die() to bypass any additional checks. internal__exit(flags()->exitcode); } - if (report) report_data = *report; - report_happened = true; ASAN_ON_ERROR(); // Make sure the registry and sanitizer report mutexes are locked while // we're printing an error report. @@ -934,6 +922,8 @@ using namespace __asan; // NOLINT void __asan_report_error(uptr pc, uptr bp, uptr sp, uptr addr, int is_write, uptr access_size) { + ScopedInErrorReport in_report; + // Determine the error type. const char *bug_descr = "unknown-crash"; if (AddrIsInMem(addr)) { @@ -981,11 +971,6 @@ void __asan_report_error(uptr pc, uptr bp, uptr sp, uptr addr, int is_write, break; } } - - ReportData report = { pc, sp, bp, addr, (bool)is_write, access_size, - bug_descr }; - ScopedInErrorReport in_report(&report); - Decorator d; Printf("%s", d.Warning()); Report("ERROR: AddressSanitizer: %s on address " @@ -1027,38 +1012,6 @@ void __asan_describe_address(uptr addr) { asanThreadRegistry().Unlock(); } -int __asan_report_present() { - return report_happened ? 1 : 0; -} - -uptr __asan_get_report_pc() { - return report_data.pc; -} - -uptr __asan_get_report_bp() { - return report_data.bp; -} - -uptr __asan_get_report_sp() { - return report_data.sp; -} - -uptr __asan_get_report_address() { - return report_data.addr; -} - -int __asan_get_report_access_type() { - return report_data.is_write ? 1 : 0; -} - -uptr __asan_get_report_access_size() { - return report_data.access_size; -} - -const char *__asan_get_report_description() { - return report_data.description; -} - extern "C" { SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_ptr_sub(void *a, void *b) { diff --git a/lib/asan/asan_report.h b/lib/asan/asan_report.h index 48fb52987..55d26a772 100644 --- a/lib/asan/asan_report.h +++ b/lib/asan/asan_report.h @@ -25,24 +25,13 @@ struct StackVarDescr { uptr name_len; }; -struct AddressDescription { - char *name; - uptr name_size; - uptr region_address; - uptr region_size; - const char *region_kind; -}; - // The following functions prints address description depending // on the memory type (shadow/heap/stack/global). void DescribeHeapAddress(uptr addr, uptr access_size); bool DescribeAddressIfGlobal(uptr addr, uptr access_size); bool DescribeAddressRelativeToGlobal(uptr addr, uptr access_size, const __asan_global &g); -bool IsAddressNearGlobal(uptr addr, const __asan_global &g); -bool GetInfoForAddressIfGlobal(uptr addr, AddressDescription *descr); -bool DescribeAddressIfShadow(uptr addr, AddressDescription *descr = nullptr, - bool print = true); +bool DescribeAddressIfShadow(uptr addr); bool ParseFrameDescription(const char *frame_descr, InternalMmapVector<StackVarDescr> *vars); bool DescribeAddressIfStack(uptr addr, uptr access_size); diff --git a/test/asan/TestCases/debug_locate.cc b/test/asan/TestCases/debug_locate.cc deleted file mode 100644 index 3015d231b..000000000 --- a/test/asan/TestCases/debug_locate.cc +++ /dev/null @@ -1,79 +0,0 @@ -// Checks the ASan memory address type debugging API, makes sure it returns -// the correct memory type for heap, stack, global and shadow addresses and -// that it correctly finds out which region (and name and size) the address -// belongs to. -// RUN: %clangxx_asan -O0 %s -o %t && %run %t 2>&1 - -#include <assert.h> -#include <sanitizer/asan_interface.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -int global_var; - -int main() { - int local_var; - char *heap_ptr = (char *)malloc(10); - - char name[100]; - void *region_address; - size_t region_size; - const char *type; - - type = __asan_locate_address(&global_var, name, 100, - ®ion_address, ®ion_size); - assert(0 == strcmp(name, "global_var")); - assert(0 == strcmp(type, "global")); - assert(region_address == &global_var); - assert(region_size == sizeof(global_var)); - - type = __asan_locate_address((char *)(&global_var)+1, name, 100, - ®ion_address, ®ion_size); - assert(0 == strcmp(name, "global_var")); - assert(0 == strcmp(type, "global")); - assert(region_address == &global_var); - assert(region_size == sizeof(global_var)); - - type = __asan_locate_address(&local_var, name, 100, - ®ion_address, ®ion_size); - assert(0 == strcmp(name, "local_var")); - assert(0 == strcmp(type, "stack")); - assert(region_address == &local_var); - assert(region_size == sizeof(local_var)); - - type = __asan_locate_address((char *)(&local_var)+1, name, 100, - ®ion_address, ®ion_size); - assert(0 == strcmp(name, "local_var")); - assert(0 == strcmp(type, "stack")); - assert(region_address == &local_var); - assert(region_size == sizeof(local_var)); - - type = __asan_locate_address(heap_ptr, name, 100, - ®ion_address, ®ion_size); - assert(0 == strcmp(type, "heap")); - assert(region_address == heap_ptr); - assert(10 == region_size); - - type = __asan_locate_address(heap_ptr+1, name, 100, - ®ion_address, ®ion_size); - assert(0 == strcmp(type, "heap")); - assert(region_address == heap_ptr); - assert(10 == region_size); - - size_t shadow_scale; - size_t shadow_offset; - __asan_get_shadow_mapping(&shadow_scale, &shadow_offset); - - intptr_t shadow_ptr = (((intptr_t)heap_ptr) >> shadow_scale) + shadow_offset; - type = __asan_locate_address((void *)shadow_ptr, NULL, 0, NULL, NULL); - assert((0 == strcmp(type, "high shadow")) || 0 == strcmp(type, "low shadow")); - - intptr_t shadow_gap = (shadow_ptr >> shadow_scale) + shadow_offset; - type = __asan_locate_address((void *)shadow_gap, NULL, 0, NULL, NULL); - assert(0 == strcmp(type, "shadow gap")); - - free(heap_ptr); - - return 0; -} diff --git a/test/asan/TestCases/debug_report.cc b/test/asan/TestCases/debug_report.cc deleted file mode 100644 index acf52f918..000000000 --- a/test/asan/TestCases/debug_report.cc +++ /dev/null @@ -1,48 +0,0 @@ -// Checks that the ASan debugging API for getting report information -// returns correct values. -// RUN: %clangxx_asan -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s - -#include <sanitizer/asan_interface.h> -#include <stdio.h> -#include <stdlib.h> - -int main() { - char *heap_ptr = (char *)malloc(10); - free(heap_ptr); - int present = __asan_report_present(); - fprintf(stderr, "%s\n", (present == 0) ? "no report" : ""); - // CHECK: no report - heap_ptr[0] = 'A'; // BOOM - return 0; -} - -void __asan_on_error() { - int present = __asan_report_present(); - void *pc = __asan_get_report_pc(); - void *bp = __asan_get_report_bp(); - void *sp = __asan_get_report_sp(); - void *addr = __asan_get_report_address(); - int is_write = __asan_get_report_access_type(); - size_t access_size = __asan_get_report_access_size(); - const char *description = __asan_get_report_description(); - - fprintf(stderr, "%s\n", (present == 1) ? "report" : ""); - // CHECK: report - fprintf(stderr, "pc: %p\n", pc); - // CHECK: pc: 0x[[PC:[0-9a-f]+]] - fprintf(stderr, "bp: %p\n", bp); - // CHECK: bp: 0x[[BP:[0-9a-f]+]] - fprintf(stderr, "sp: %p\n", sp); - // CHECK: sp: 0x[[SP:[0-9a-f]+]] - fprintf(stderr, "addr: %p\n", addr); - // CHECK: addr: 0x[[ADDR:[0-9a-f]+]] - fprintf(stderr, "type: %s\n", (is_write ? "write" : "read")); - // CHECK: type: write - fprintf(stderr, "access_size: %ld\n", access_size); - // CHECK: access_size: 1 - fprintf(stderr, "description: %s\n", description); - // CHECK: description: heap-use-after-free -} - -// CHECK: AddressSanitizer: heap-use-after-free on address {{0x0*}}[[ADDR]] at pc {{0x0*}}[[PC]] bp {{0x0*}}[[BP]] sp {{0x0*}}[[SP]] -// CHECK: WRITE of size 1 at {{0x0*}}[[ADDR]] thread T0 |