[compiler-rt] dc7498e - [hwasan] Record allocation thread id in HeapAllocationRecord
via llvm-commits
llvm-commits at lists.llvm.org
Mon Apr 3 20:26:13 PDT 2023
Author: Enna1
Date: 2023-04-04T11:25:18+08:00
New Revision: dc7498eb027b512091159731163327a0ff4f182e
URL: https://github.com/llvm/llvm-project/commit/dc7498eb027b512091159731163327a0ff4f182e
DIFF: https://github.com/llvm/llvm-project/commit/dc7498eb027b512091159731163327a0ff4f182e.diff
LOG: [hwasan] Record allocation thread id in HeapAllocationRecord
Extend HeapAllocationRecord to record allocation thread id, print thread id in memory allocation stack trace.
Reviewed By: vitalybuka
Differential Revision: https://reviews.llvm.org/D147215
Added:
Modified:
compiler-rt/lib/hwasan/hwasan_allocator.cpp
compiler-rt/lib/hwasan/hwasan_allocator.h
compiler-rt/lib/hwasan/hwasan_report.cpp
compiler-rt/test/hwasan/TestCases/double-free.c
compiler-rt/test/hwasan/TestCases/hwasan_symbolize.cpp
compiler-rt/test/hwasan/TestCases/realloc-after-free.c
compiler-rt/test/hwasan/TestCases/set-error-report-callback.cpp
compiler-rt/test/hwasan/TestCases/tag_in_free.c
compiler-rt/test/hwasan/TestCases/thread-uaf.c
compiler-rt/test/hwasan/TestCases/use-after-free.c
Removed:
################################################################################
diff --git a/compiler-rt/lib/hwasan/hwasan_allocator.cpp b/compiler-rt/lib/hwasan/hwasan_allocator.cpp
index 994a580dc95e0..e6f46ed0933c1 100644
--- a/compiler-rt/lib/hwasan/hwasan_allocator.cpp
+++ b/compiler-rt/lib/hwasan/hwasan_allocator.cpp
@@ -64,6 +64,10 @@ u32 HwasanChunkView::GetAllocStackId() const {
return metadata_->GetAllocStackId();
}
+u32 HwasanChunkView::GetAllocThreadId() const {
+ return metadata_->GetAllocThreadId();
+}
+
uptr HwasanChunkView::ActualSize() const {
return allocator.GetActuallyAllocatedSize(reinterpret_cast<void *>(block_));
}
@@ -106,6 +110,12 @@ inline u32 Metadata::GetAllocStackId() const {
return atomic_load(&alloc_context_id, memory_order_relaxed);
}
+inline u32 Metadata::GetAllocThreadId() const {
+ u64 context = atomic_load(&alloc_context_id, memory_order_relaxed);
+ u32 tid = context >> 32;
+ return tid;
+}
+
void GetAllocatorStats(AllocatorStatCounters s) {
allocator.GetStats(s);
}
@@ -296,6 +306,7 @@ static void HwasanDeallocate(StackTrace *stack, void *tagged_ptr) {
uptr orig_size = meta->GetRequestedSize();
u32 free_context_id = StackDepotPut(*stack);
u32 alloc_context_id = meta->GetAllocStackId();
+ u32 alloc_thread_id = meta->GetAllocThreadId();
// Check tail magic.
uptr tagged_size = TaggedSize(orig_size);
@@ -347,8 +358,9 @@ static void HwasanDeallocate(StackTrace *stack, void *tagged_ptr) {
if (t) {
allocator.Deallocate(t->allocator_cache(), aligned_ptr);
if (auto *ha = t->heap_allocations())
- ha->push({reinterpret_cast<uptr>(tagged_ptr), alloc_context_id,
- free_context_id, static_cast<u32>(orig_size)});
+ ha->push({reinterpret_cast<uptr>(tagged_ptr), alloc_thread_id,
+ alloc_context_id, free_context_id,
+ static_cast<u32>(orig_size)});
} else {
SpinMutexLock l(&fallback_mutex);
AllocatorCache *cache = &fallback_allocator_cache;
diff --git a/compiler-rt/lib/hwasan/hwasan_allocator.h b/compiler-rt/lib/hwasan/hwasan_allocator.h
index 2093079413014..b7a06da0b6534 100644
--- a/compiler-rt/lib/hwasan/hwasan_allocator.h
+++ b/compiler-rt/lib/hwasan/hwasan_allocator.h
@@ -46,6 +46,7 @@ struct Metadata {
inline bool IsAllocated() const;
inline u64 GetRequestedSize() const;
inline u32 GetAllocStackId() const;
+ inline u32 GetAllocThreadId() const;
inline void SetLsanTag(__lsan::ChunkTag tag);
inline __lsan::ChunkTag GetLsanTag() const;
};
@@ -100,6 +101,7 @@ class HwasanChunkView {
uptr UsedSize() const; // Size requested by the user
uptr ActualSize() const; // Size allocated by the allocator.
u32 GetAllocStackId() const;
+ u32 GetAllocThreadId() const;
bool FromSmallHeap() const;
bool AddrIsInside(uptr addr) const;
@@ -113,13 +115,12 @@ HwasanChunkView FindHeapChunkByAddress(uptr address);
// Information about one (de)allocation that happened in the past.
// These are recorded in a thread-local ring buffer.
-// TODO: this is currently 24 bytes (20 bytes + alignment).
-// Compress it to 16 bytes or extend it to be more useful.
struct HeapAllocationRecord {
uptr tagged_addr;
- u32 alloc_context_id;
- u32 free_context_id;
- u32 requested_size;
+ u32 alloc_thread_id;
+ u32 alloc_context_id;
+ u32 free_context_id;
+ u32 requested_size;
};
typedef RingBuffer<HeapAllocationRecord> HeapAllocationsRingBuffer;
diff --git a/compiler-rt/lib/hwasan/hwasan_report.cpp b/compiler-rt/lib/hwasan/hwasan_report.cpp
index 31e190a8ebbcf..e720cb467a051 100644
--- a/compiler-rt/lib/hwasan/hwasan_report.cpp
+++ b/compiler-rt/lib/hwasan/hwasan_report.cpp
@@ -331,7 +331,7 @@ static void ShowHeapOrGlobalCandidate(uptr untagged_addr, tag_t *candidate,
untagged_addr, offset, whence, chunk.UsedSize(), chunk.Beg(),
chunk.End());
Printf("%s", d.Allocation());
- Printf("allocated here:\n");
+ Printf("allocated by thread T%u here:\n", chunk.GetAllocThreadId());
Printf("%s", d.Default());
GetStackTraceFromId(chunk.GetAllocStackId()).Print();
return;
@@ -473,12 +473,12 @@ void PrintAddressDescription(
har.requested_size, UntagAddr(har.tagged_addr),
UntagAddr(har.tagged_addr) + har.requested_size);
Printf("%s", d.Allocation());
- Printf("freed by thread T%zd here:\n", t->unique_id());
+ 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 here:\n", t);
+ Printf("previously allocated by thread T%u here:\n", har.alloc_thread_id);
Printf("%s", d.Default());
GetStackTraceFromId(har.alloc_context_id).Print();
diff --git a/compiler-rt/test/hwasan/TestCases/double-free.c b/compiler-rt/test/hwasan/TestCases/double-free.c
index 6d177fdef7029..ec15dc300018f 100644
--- a/compiler-rt/test/hwasan/TestCases/double-free.c
+++ b/compiler-rt/test/hwasan/TestCases/double-free.c
@@ -18,7 +18,7 @@ int main() {
// of the fault. With TCO the free frame can be replaced with the interceptor.
// CHECK: in {{.*}}free
// CHECK: freed by thread {{.*}} here:
- // CHECK: previously allocated here:
+ // CHECK: previously allocated by thread {{.*}} here:
// CHECK: Memory tags around the buggy address (one tag corresponds to 16 bytes):
// CHECK: =>{{.*}}[[MEM_TAG]]
fprintf(stderr, "DONE\n");
diff --git a/compiler-rt/test/hwasan/TestCases/hwasan_symbolize.cpp b/compiler-rt/test/hwasan/TestCases/hwasan_symbolize.cpp
index abd8bc42a34bb..2cb807cd3c762 100644
--- a/compiler-rt/test/hwasan/TestCases/hwasan_symbolize.cpp
+++ b/compiler-rt/test/hwasan/TestCases/hwasan_symbolize.cpp
@@ -18,7 +18,7 @@ int main(int argc, char **argv) {
// LINKIFY: <a href="http://test.invalid/hwasan_symbolize.cpp:[[@LINE-1]]">
// CHECK: hwasan_symbolize.cpp:[[@LINE-2]]
// CHECK: Cause: heap-buffer-overflow
- // CHECK: allocated here:
+ // CHECK: allocated by thread {{.*}} here:
// LINKIFY: <a href="http://test.invalid/hwasan_symbolize.cpp:[[@LINE-6]]">
// CHECK: hwasan_symbolize.cpp:[[@LINE-7]]
return 0;
diff --git a/compiler-rt/test/hwasan/TestCases/realloc-after-free.c b/compiler-rt/test/hwasan/TestCases/realloc-after-free.c
index c4bc48c9ccda2..393048c4eba9f 100644
--- a/compiler-rt/test/hwasan/TestCases/realloc-after-free.c
+++ b/compiler-rt/test/hwasan/TestCases/realloc-after-free.c
@@ -16,12 +16,12 @@ int main(int argc, char **argv) {
char * volatile x = (char*)malloc(40);
free(x);
x = realloc(x, realloc_size);
-// CHECK: ERROR: HWAddressSanitizer: invalid-free on address
-// CHECK: tags: [[PTR_TAG:..]]/[[MEM_TAG:..]] (ptr/mem)
-// CHECK: freed by thread {{.*}} here:
-// CHECK: previously allocated here:
-// CHECK: Memory tags around the buggy address (one tag corresponds to 16 bytes):
-// CHECK: =>{{.*}}[[MEM_TAG]]
+ // CHECK: ERROR: HWAddressSanitizer: invalid-free on address
+ // CHECK: tags: [[PTR_TAG:..]]/[[MEM_TAG:..]] (ptr/mem)
+ // CHECK: freed by thread {{.*}} here:
+ // CHECK: previously allocated by thread {{.*}} here:
+ // CHECK: Memory tags around the buggy address (one tag corresponds to 16 bytes):
+ // CHECK: =>{{.*}}[[MEM_TAG]]
fprintf(stderr, "DONE\n");
__hwasan_disable_allocator_tagging();
// CHECK-NOT: DONE
diff --git a/compiler-rt/test/hwasan/TestCases/set-error-report-callback.cpp b/compiler-rt/test/hwasan/TestCases/set-error-report-callback.cpp
index c2a20be75defc..42a57365d3914 100644
--- a/compiler-rt/test/hwasan/TestCases/set-error-report-callback.cpp
+++ b/compiler-rt/test/hwasan/TestCases/set-error-report-callback.cpp
@@ -17,13 +17,13 @@ int main() {
free(p);
// CHECK: ERROR: HWAddressSanitizer:
// CHECK: WRITE of size 1 at
- // CHECK: allocated here:
+ // CHECK: allocated by thread {{.*}} here:
// CHECK: Memory tags around the buggy address
// CHECK: == error start
// CHECK: ERROR: HWAddressSanitizer:
// CHECK: WRITE of size 1 at
- // CHECK: allocated here:
+ // CHECK: allocated by thread {{.*}} here:
// CHECK: Memory tags around the buggy address
// CHECK: == error end
}
diff --git a/compiler-rt/test/hwasan/TestCases/tag_in_free.c b/compiler-rt/test/hwasan/TestCases/tag_in_free.c
index 5c8dd65d56b7c..fba96dd188bac 100644
--- a/compiler-rt/test/hwasan/TestCases/tag_in_free.c
+++ b/compiler-rt/test/hwasan/TestCases/tag_in_free.c
@@ -33,7 +33,7 @@ int main() {
#ifdef MALLOC
// MALLOC: READ of size 1 at
// MALLOC: is located 6 bytes after a 10-byte region
- // MALLOC: allocated here:
+ // MALLOC: allocated by thread T0 here:
char volatile x = p[16];
#endif
free(p);
@@ -41,7 +41,7 @@ int main() {
// FREE: READ of size 1 at
// FREE: is located 0 bytes inside a 10-byte region
// FREE: freed by thread T0 here:
- // FREE: previously allocated here:
+ // FREE: previously allocated by thread T0 here:
char volatile y = p[0];
#endif
diff --git a/compiler-rt/test/hwasan/TestCases/thread-uaf.c b/compiler-rt/test/hwasan/TestCases/thread-uaf.c
index c368882f45896..478c1c98478ca 100644
--- a/compiler-rt/test/hwasan/TestCases/thread-uaf.c
+++ b/compiler-rt/test/hwasan/TestCases/thread-uaf.c
@@ -33,7 +33,7 @@ void *Use(void *arg) {
// CHECK: Cause: use-after-free
// CHECK: freed by thread T2 here
// CHECK: in Deallocate
- // CHECK: previously allocated here:
+ // CHECK: previously allocated by thread T1 here:
// CHECK: in Allocate
// CHECK-DAG: Thread: T2 0x
// CHECK-DAG: Thread: T3 0x
diff --git a/compiler-rt/test/hwasan/TestCases/use-after-free.c b/compiler-rt/test/hwasan/TestCases/use-after-free.c
index 24546374341e3..266e934e76f4b 100644
--- a/compiler-rt/test/hwasan/TestCases/use-after-free.c
+++ b/compiler-rt/test/hwasan/TestCases/use-after-free.c
@@ -35,7 +35,7 @@ int main() {
// CHECK: #0 {{.*}} in {{.*}}free{{.*}} {{.*}}hwasan_allocation_functions.cpp
// CHECK: #1 {{.*}} in main {{.*}}use-after-free.c:[[@LINE-19]]
- // CHECK: previously allocated here:
+ // CHECK: previously allocated by thread {{.*}} here:
// CHECK: #0 {{.*}} in {{.*}}malloc{{.*}} {{.*}}hwasan_allocation_functions.cpp
// CHECK: #1 {{.*}} in main {{.*}}use-after-free.c:[[@LINE-24]]
// CHECK: Memory tags around the buggy address (one tag corresponds to 16 bytes):
More information about the llvm-commits
mailing list