[compiler-rt] 41934f2 - [NFC][hwasan] Collect heap allocations early (#66682)
Vitaly Buka via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 19 19:33:42 PDT 2023
Author: Vitaly Buka
Date: 2023-09-19T19:29:33-07:00
New Revision: 41934f2d1f8f5d4f7e2139cbf47318957822d38b
URL: https://github.com/llvm/llvm-project/commit/41934f2d1f8f5d4f7e2139cbf47318957822d38b
DIFF: https://github.com/llvm/llvm-project/commit/41934f2d1f8f5d4f7e2139cbf47318957822d38b.diff
LOG: [NFC][hwasan] Collect heap allocations early (#66682)
Added:
Modified:
compiler-rt/lib/hwasan/hwasan_report.cpp
Removed:
################################################################################
diff --git a/compiler-rt/lib/hwasan/hwasan_report.cpp b/compiler-rt/lib/hwasan/hwasan_report.cpp
index c7683698a76de07..442c5b736611dfb 100644
--- a/compiler-rt/lib/hwasan/hwasan_report.cpp
+++ b/compiler-rt/lib/hwasan/hwasan_report.cpp
@@ -391,7 +391,7 @@ class BaseReport {
return;
CopyHeapChunk();
- CopyStackAllocations();
+ CopyAllocations();
candidate = FindBufferOverflowCandidate();
}
@@ -411,7 +411,7 @@ class BaseReport {
};
void CopyHeapChunk();
- void CopyStackAllocations();
+ void CopyAllocations();
OverflowCandidate FindBufferOverflowCandidate() const;
void PrintAddressDescription() const;
void PrintHeapOrGlobalCandidate() const;
@@ -434,6 +434,15 @@ class BaseReport {
} heap;
OverflowCandidate candidate;
+
+ uptr heap_allocations_count = 0;
+ struct {
+ HeapAllocationRecord har = {};
+ uptr ring_index = 0;
+ uptr num_matching_addrs = 0;
+ uptr num_matching_addrs_4b = 0;
+ u32 free_thread_id = 0;
+ } heap_allocations[256];
};
void BaseReport::CopyHeapChunk() {
@@ -446,12 +455,28 @@ void BaseReport::CopyHeapChunk() {
}
}
-void BaseReport::CopyStackAllocations() {
+void BaseReport::CopyAllocations() {
hwasanThreadList().VisitAllLiveThreads([&](Thread *t) {
if (stack_allocations_count < ARRAY_SIZE(stack_allocations) &&
t->AddrIsInStack(untagged_addr)) {
stack_allocations[stack_allocations_count++].CopyFrom(t);
}
+
+ if (heap_allocations_count < ARRAY_SIZE(heap_allocations)) {
+ // Scan all threads' ring buffers to find if it's a heap-use-after-free.
+ HeapAllocationRecord har;
+ uptr ring_index, num_matching_addrs, num_matching_addrs_4b;
+ if (FindHeapAllocation(t->heap_allocations(), tagged_addr, &har,
+ &ring_index, &num_matching_addrs,
+ &num_matching_addrs_4b)) {
+ auto &ha = heap_allocations[heap_allocations_count++];
+ ha.har = har;
+ ha.ring_index = ring_index;
+ ha.num_matching_addrs = num_matching_addrs;
+ ha.num_matching_addrs_4b = num_matching_addrs_4b;
+ ha.free_thread_id = t->unique_id();
+ }
+ }
});
}
@@ -616,42 +641,39 @@ void BaseReport::PrintAddressDescription() const {
num_descriptions_printed++;
}
- hwasanThreadList().VisitAllLiveThreads([&](Thread *t) {
- // Scan all threads' ring buffers to find if it's a heap-use-after-free.
- HeapAllocationRecord har;
- uptr ring_index, num_matching_addrs, num_matching_addrs_4b;
- if (FindHeapAllocation(t->heap_allocations(), tagged_addr, &har,
- &ring_index, &num_matching_addrs,
- &num_matching_addrs_4b)) {
- Printf("%s", d.Error());
- Printf("\nCause: use-after-free\n");
- Printf("%s", d.Location());
- Printf("%p is located %zd bytes inside a %zd-byte region [%p,%p)\n",
- untagged_addr, untagged_addr - UntagAddr(har.tagged_addr),
- har.requested_size, UntagAddr(har.tagged_addr),
- UntagAddr(har.tagged_addr) + har.requested_size);
- Printf("%s", d.Allocation());
- Printf("freed by thread T%u here:\n", t->unique_id());
- Printf("%s", d.Default());
- GetStackTraceFromId(har.free_context_id).Print();
-
- Printf("%s", d.Allocation());
- Printf("previously allocated by thread T%u here:\n", har.alloc_thread_id);
- Printf("%s", d.Default());
- GetStackTraceFromId(har.alloc_context_id).Print();
-
- // Print a developer note: the index of this heap object
- // in the thread's deallocation ring buffer.
- Printf("hwasan_dev_note_heap_rb_distance: %zd %zd\n", ring_index + 1,
- flags()->heap_history_size);
- Printf("hwasan_dev_note_num_matching_addrs: %zd\n", num_matching_addrs);
- Printf("hwasan_dev_note_num_matching_addrs_4b: %zd\n",
- num_matching_addrs_4b);
-
- t->Announce();
- num_descriptions_printed++;
- }
- });
+ for (uptr i = 0; i < heap_allocations_count; ++i) {
+ const auto &ha = heap_allocations[i];
+ const HeapAllocationRecord har = ha.har;
+
+ Printf("%s", d.Error());
+ Printf("\nCause: use-after-free\n");
+ Printf("%s", d.Location());
+ Printf("%p is located %zd bytes inside a %zd-byte region [%p,%p)\n",
+ untagged_addr, untagged_addr - UntagAddr(har.tagged_addr),
+ har.requested_size, UntagAddr(har.tagged_addr),
+ UntagAddr(har.tagged_addr) + har.requested_size);
+ Printf("%s", d.Allocation());
+ Printf("freed by thread T%u here:\n", ha.free_thread_id);
+ Printf("%s", d.Default());
+ GetStackTraceFromId(har.free_context_id).Print();
+
+ Printf("%s", d.Allocation());
+ Printf("previously allocated by thread T%u here:\n", har.alloc_thread_id);
+ Printf("%s", d.Default());
+ GetStackTraceFromId(har.alloc_context_id).Print();
+
+ // Print a developer note: the index of this heap object
+ // in the thread's deallocation ring buffer.
+ Printf("hwasan_dev_note_heap_rb_distance: %zd %zd\n", ha.ring_index + 1,
+ flags()->heap_history_size);
+ Printf("hwasan_dev_note_num_matching_addrs: %zd\n", ha.num_matching_addrs);
+ Printf("hwasan_dev_note_num_matching_addrs_4b: %zd\n",
+ ha.num_matching_addrs_4b);
+
+ announce_by_id(ha.free_thread_id);
+ // TODO: announce_by_id(har.alloc_thread_id);
+ num_descriptions_printed++;
+ }
if (candidate.untagged_addr && num_descriptions_printed == 0) {
PrintHeapOrGlobalCandidate();
More information about the llvm-commits
mailing list