diff --git a/compiler-rt/include/sanitizer/asan_interface.h b/compiler-rt/include/sanitizer/asan_interface.h --- a/compiler-rt/include/sanitizer/asan_interface.h +++ b/compiler-rt/include/sanitizer/asan_interface.h @@ -315,6 +315,10 @@ /// functions like _exit() and execl(). void __asan_handle_no_return(void); +/// Update allocation stack trace for the given allocation to the current stack +/// trace. Returns 1 if successfull, 0 if not. +int __asan_update_allocation(void* addr); + #ifdef __cplusplus } // extern "C" #endif diff --git a/compiler-rt/lib/asan/asan_allocator.cpp b/compiler-rt/lib/asan/asan_allocator.cpp --- a/compiler-rt/lib/asan/asan_allocator.cpp +++ b/compiler-rt/lib/asan/asan_allocator.cpp @@ -394,6 +394,15 @@ return right_chunk; } + bool UpdateAllocationStack(uptr addr, BufferedStackTrace *stack) { + AsanChunk *m = GetAsanChunkByAddr(addr); + if (!m) return false; + if (m->chunk_state != CHUNK_ALLOCATED) return false; + if (m->Beg() != addr) return false; + m->alloc_context_id = StackDepotPut(*stack); + return true; + } + // -------------------- Allocation/Deallocation routines --------------- void *Allocate(uptr size, uptr alignment, BufferedStackTrace *stack, AllocType alloc_type, bool can_fill) { @@ -1105,6 +1114,11 @@ instance.Purge(&stack); } +int __asan_update_allocation(void* addr) { + GET_STACK_TRACE_MALLOC; + return instance.UpdateAllocationStack((uptr)addr, &stack); +} + #if !SANITIZER_SUPPORTS_WEAK_HOOKS // Provide default (no-op) implementation of malloc hooks. SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_malloc_hook, diff --git a/compiler-rt/lib/asan/asan_interface_internal.h b/compiler-rt/lib/asan/asan_interface_internal.h --- a/compiler-rt/lib/asan/asan_interface_internal.h +++ b/compiler-rt/lib/asan/asan_interface_internal.h @@ -251,6 +251,8 @@ const char* __asan_default_suppressions(); SANITIZER_INTERFACE_ATTRIBUTE void __asan_handle_vfork(void *sp); + + SANITIZER_INTERFACE_ATTRIBUTE int __asan_update_allocation(void* addr); } // extern "C" #endif // ASAN_INTERFACE_INTERNAL_H diff --git a/compiler-rt/test/asan/TestCases/asan_update_allocation.cpp b/compiler-rt/test/asan/TestCases/asan_update_allocation.cpp new file mode 100644 --- /dev/null +++ b/compiler-rt/test/asan/TestCases/asan_update_allocation.cpp @@ -0,0 +1,19 @@ +// RUN: %clangxx_asan -O0 -DSIZE=10 %s -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-%os --check-prefix=CHECK +// RUN: %clangxx_asan -O0 -DSIZE=10000000 %s -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-%os --check-prefix=CHECK +// REQUIRES: stable-runtime + +#include +#include + +void UPDATE(void *p) { + __asan_update_allocation(p); +} + +int main() { + char *x = (char*)malloc(SIZE * sizeof(char)); + UPDATE(x); + free(x); + return x[5]; + // CHECK: {{.*ERROR: AddressSanitizer: heap-use-after-free on address}} + // CHECK: UPDATE +}