diff options
Diffstat (limited to 'gnu/llvm/compiler-rt/lib/gwp_asan/tests/backtrace.cpp')
-rw-r--r-- | gnu/llvm/compiler-rt/lib/gwp_asan/tests/backtrace.cpp | 71 |
1 files changed, 57 insertions, 14 deletions
diff --git a/gnu/llvm/compiler-rt/lib/gwp_asan/tests/backtrace.cpp b/gnu/llvm/compiler-rt/lib/gwp_asan/tests/backtrace.cpp index 6dccdb8c001..b3d44270bb2 100644 --- a/gnu/llvm/compiler-rt/lib/gwp_asan/tests/backtrace.cpp +++ b/gnu/llvm/compiler-rt/lib/gwp_asan/tests/backtrace.cpp @@ -8,34 +8,77 @@ #include <string> +#include "gwp_asan/crash_handler.h" #include "gwp_asan/tests/harness.h" -TEST_F(BacktraceGuardedPoolAllocator, DoubleFree) { - void *Ptr = GPA.allocate(1); +// Optnone to ensure that the calls to these functions are not optimized away, +// as we're looking for them in the backtraces. +__attribute((optnone)) void * +AllocateMemory(gwp_asan::GuardedPoolAllocator &GPA) { + return GPA.allocate(1); +} +__attribute((optnone)) void +DeallocateMemory(gwp_asan::GuardedPoolAllocator &GPA, void *Ptr) { + GPA.deallocate(Ptr); +} +__attribute((optnone)) void +DeallocateMemory2(gwp_asan::GuardedPoolAllocator &GPA, void *Ptr) { GPA.deallocate(Ptr); +} +__attribute__((optnone)) void TouchMemory(void *Ptr) { + *(reinterpret_cast<volatile char *>(Ptr)) = 7; +} - std::string DeathRegex = "Double free.*"; - DeathRegex.append("backtrace\\.cpp:25.*"); +TEST_F(BacktraceGuardedPoolAllocator, DoubleFree) { + void *Ptr = AllocateMemory(GPA); + DeallocateMemory(GPA, Ptr); + + std::string DeathRegex = "Double Free.*"; + DeathRegex.append("DeallocateMemory2.*"); DeathRegex.append("was deallocated.*"); - DeathRegex.append("backtrace\\.cpp:15.*"); + DeathRegex.append("DeallocateMemory.*"); DeathRegex.append("was allocated.*"); - DeathRegex.append("backtrace\\.cpp:14.*"); - ASSERT_DEATH(GPA.deallocate(Ptr), DeathRegex); + DeathRegex.append("AllocateMemory.*"); + ASSERT_DEATH(DeallocateMemory2(GPA, Ptr), DeathRegex); } TEST_F(BacktraceGuardedPoolAllocator, UseAfterFree) { - char *Ptr = static_cast<char *>(GPA.allocate(1)); - GPA.deallocate(Ptr); + void *Ptr = AllocateMemory(GPA); + DeallocateMemory(GPA, Ptr); - std::string DeathRegex = "Use after free.*"; - DeathRegex.append("backtrace\\.cpp:40.*"); + std::string DeathRegex = "Use After Free.*"; + DeathRegex.append("TouchMemory.*"); DeathRegex.append("was deallocated.*"); - DeathRegex.append("backtrace\\.cpp:30.*"); + DeathRegex.append("DeallocateMemory.*"); DeathRegex.append("was allocated.*"); - DeathRegex.append("backtrace\\.cpp:29.*"); - ASSERT_DEATH({ *Ptr = 7; }, DeathRegex); + DeathRegex.append("AllocateMemory.*"); + ASSERT_DEATH(TouchMemory(Ptr), DeathRegex); +} + +TEST(Backtrace, Short) { + gwp_asan::AllocationMetadata Meta; + Meta.AllocationTrace.RecordBacktrace( + [](uintptr_t *TraceBuffer, size_t /* Size */) -> size_t { + TraceBuffer[0] = 123u; + TraceBuffer[1] = 321u; + return 2u; + }); + uintptr_t TraceOutput[2] = {}; + EXPECT_EQ(2u, __gwp_asan_get_allocation_trace(&Meta, TraceOutput, 2)); + EXPECT_EQ(TraceOutput[0], 123u); + EXPECT_EQ(TraceOutput[1], 321u); +} + +TEST(Backtrace, ExceedsStorableLength) { + gwp_asan::AllocationMetadata Meta; + Meta.AllocationTrace.RecordBacktrace( + [](uintptr_t * /* TraceBuffer */, size_t /* Size */) -> size_t { + return SIZE_MAX; // Wow, that's big! + }); + uintptr_t TraceOutput; + EXPECT_EQ(1u, __gwp_asan_get_allocation_trace(&Meta, &TraceOutput, 1)); } |