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
+}