From c1d6fd5a053a583bd304e91a90272674ea7df045 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Thu, 18 Aug 2016 17:47:34 -0700 Subject: [PATCH] Subzero: Added address of bad instruction to error output BUG=https://bugs.chromium.org/p/nativeclient/issues/detail?id=4374 R=stichnot@chromium.org Review URL: https://codereview.chromium.org/2256673004 . --- runtime/szrt_asan.c | 17 ++++++++++------- tests_lit/asan_tests/doublefree.ll | 1 + tests_lit/asan_tests/errors.ll | 4 ++++ 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/runtime/szrt_asan.c b/runtime/szrt_asan.c index 302ed9a0b..94fc47a4d 100644 --- a/runtime/szrt_asan.c +++ b/runtime/szrt_asan.c @@ -90,7 +90,7 @@ static const char *access_names[] = {"load from", "store to"}; static char *shadow_offset = NULL; static bool __asan_check(char *, int); -static void __asan_error(char *, int, int); +static void __asan_error(char *, int, int, void *); static void __asan_get_redzones(char *, char **, char **); void __asan_init(int, void **, int *); @@ -113,7 +113,7 @@ uint64_t quarantine_size = 0; struct quarantine_entry *quarantine_head = NULL; struct quarantine_entry *quarantine_tail = NULL; -static void __asan_error(char *ptr, int size, int access) { +static void __asan_error(char *ptr, int size, int access, void *ret_addr) { char *shadow_addr = MEM2SHADOW(ptr); char shadow_val = *shadow_addr; if (shadow_val > 0) @@ -123,8 +123,9 @@ static void __asan_error(char *ptr, int size, int access) { assert(shadow_val == STACK_POISON_VAL || shadow_val == HEAP_POISON_VAL || shadow_val == GLOBAL_POISON_VAL || shadow_val == FREED_POISON_VAL); const char *memtype = memtype_names[MEMTYPE_INDEX(shadow_val)]; - fprintf(stderr, "Illegal %d byte %s %s object at %p\n", size, access_name, - memtype, ptr); + fprintf(stderr, "%p: Illegal %d byte %s %s object at %p\n", ret_addr, size, + access_name, memtype, ptr); + fprintf(stderr, "(address of __asan_error symbol is %p)\n", __asan_error); abort(); } @@ -156,13 +157,13 @@ void __asan_check_load(char *ptr, int size) { int check_size = (size == WORD_SIZE && (uintptr_t)ptr % WORD_SIZE == 0) ? 1 : size; if (!__asan_check(ptr, check_size)) - __asan_error(ptr, size, ACCESS_LOAD); + __asan_error(ptr, size, ACCESS_LOAD, __builtin_return_address(0)); } void __asan_check_store(char *ptr, int size) { // stores may never be partially out of bounds so use strict check if (!__asan_check(ptr, size)) - __asan_error(ptr, size, ACCESS_STORE); + __asan_error(ptr, size, ACCESS_STORE, __builtin_return_address(0)); } void __asan_init(int n_rzs, void **rzs, int *rz_sizes) { @@ -250,7 +251,9 @@ void __asan_free(char *ptr) { if (ptr == NULL) return; if (*(char *)MEM2SHADOW(ptr) == FREED_POISON_VAL) { - fprintf(stderr, "Double free of object at %p\n", ptr); + fprintf(stderr, "%p: Double free of object at %p\n", + __builtin_return_address(0), ptr); + fprintf(stderr, "(address of __asan_error symbol is %p)\n", __asan_error); abort(); } char *rz_left, *rz_right; diff --git a/tests_lit/asan_tests/doublefree.ll b/tests_lit/asan_tests/doublefree.ll index ca79ec415..88e03e991 100644 --- a/tests_lit/asan_tests/doublefree.ll +++ b/tests_lit/asan_tests/doublefree.ll @@ -22,3 +22,4 @@ define void @_start(i32 %arg) { } ; ERR: Double free of object at +; ERR-NEXT: address of __asan_error symbol is diff --git a/tests_lit/asan_tests/errors.ll b/tests_lit/asan_tests/errors.ll index cc403cce6..d058ab2b3 100644 --- a/tests_lit/asan_tests/errors.ll +++ b/tests_lit/asan_tests/errors.ll @@ -223,6 +223,10 @@ error: } ; LOCAL-LOAD: Illegal 1 byte load from stack object at +; LOCAL-LOAD-NEXT: address of __asan_error symbol is ; LOCAL-STORE: Illegal 1 byte store to stack object at +; LOCAL-STORE-NEXT: address of __asan_error symbol is ; GLOBAL-LOAD: Illegal 1 byte load from global object at +; GLOBAL-LOAD-NEXT: address of __asan_error symbol is ; GLOBAL-STORE: Illegal 1 byte store to global object at +; GLOBAL-STORE-NEXT: address of __asan_error symbol is -- 2.11.0