Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / compiler-rt / lib / gwp_asan / tests / crash_handler_api.cpp
blobd270ed8f3c4163a846552013bf2d5f702ef6f66f
1 //===-- crash_handler_api.cpp -----------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #include "gwp_asan/crash_handler.h"
10 #include "gwp_asan/guarded_pool_allocator.h"
11 #include "gwp_asan/stack_trace_compressor.h"
12 #include "gwp_asan/tests/harness.h"
14 using Error = gwp_asan::Error;
15 using GuardedPoolAllocator = gwp_asan::GuardedPoolAllocator;
16 using AllocationMetadata = gwp_asan::AllocationMetadata;
17 using AllocatorState = gwp_asan::AllocatorState;
19 class CrashHandlerAPITest : public ::testing::Test {
20 public:
21 void SetUp() override { setupState(); }
23 protected:
24 size_t metadata(uintptr_t Addr, uintptr_t Size, bool IsDeallocated) {
25 // Should only be allocating the 0x3000, 0x5000, 0x7000, 0x9000 pages.
26 EXPECT_GE(Addr, 0x3000u);
27 EXPECT_LT(Addr, 0xa000u);
29 size_t Slot = State.getNearestSlot(Addr);
31 Metadata[Slot].Addr = Addr;
32 Metadata[Slot].RequestedSize = Size;
33 Metadata[Slot].IsDeallocated = IsDeallocated;
34 Metadata[Slot].AllocationTrace.ThreadID = 123;
35 Metadata[Slot].DeallocationTrace.ThreadID = 321;
36 setupBacktraces(&Metadata[Slot]);
38 return Slot;
41 void setupState() {
42 State.GuardedPagePool = 0x2000;
43 State.GuardedPagePoolEnd = 0xc000;
44 InternalFaultAddr = State.GuardedPagePoolEnd - 0x10;
45 State.MaxSimultaneousAllocations = 4; // 0x3000, 0x5000, 0x7000, 0x9000.
46 State.PageSize = 0x1000;
49 void setupBacktraces(AllocationMetadata *Meta) {
50 Meta->AllocationTrace.TraceSize = gwp_asan::compression::pack(
51 BacktraceConstants, kNumBacktraceConstants,
52 Meta->AllocationTrace.CompressedTrace,
53 AllocationMetadata::kStackFrameStorageBytes);
55 if (Meta->IsDeallocated)
56 Meta->DeallocationTrace.TraceSize = gwp_asan::compression::pack(
57 BacktraceConstants, kNumBacktraceConstants,
58 Meta->DeallocationTrace.CompressedTrace,
59 AllocationMetadata::kStackFrameStorageBytes);
62 void checkBacktrace(const AllocationMetadata *Meta, bool IsDeallocated) {
63 uintptr_t Buffer[kNumBacktraceConstants];
64 size_t NumBacktraceConstants = kNumBacktraceConstants;
65 EXPECT_EQ(NumBacktraceConstants, __gwp_asan_get_allocation_trace(
66 Meta, Buffer, kNumBacktraceConstants));
67 for (size_t i = 0; i < kNumBacktraceConstants; ++i)
68 EXPECT_EQ(Buffer[i], BacktraceConstants[i]);
70 if (IsDeallocated) {
71 EXPECT_EQ(NumBacktraceConstants,
72 __gwp_asan_get_deallocation_trace(Meta, Buffer,
73 kNumBacktraceConstants));
74 for (size_t i = 0; i < kNumBacktraceConstants; ++i)
75 EXPECT_EQ(Buffer[i], BacktraceConstants[i]);
79 void checkMetadata(size_t Index, uintptr_t ErrorPtr) {
80 const AllocationMetadata *Meta =
81 __gwp_asan_get_metadata(&State, Metadata, ErrorPtr);
82 EXPECT_NE(nullptr, Meta);
83 EXPECT_EQ(Metadata[Index].Addr, __gwp_asan_get_allocation_address(Meta));
84 EXPECT_EQ(Metadata[Index].RequestedSize,
85 __gwp_asan_get_allocation_size(Meta));
86 EXPECT_EQ(Metadata[Index].AllocationTrace.ThreadID,
87 __gwp_asan_get_allocation_thread_id(Meta));
89 bool IsDeallocated = __gwp_asan_is_deallocated(Meta);
90 EXPECT_EQ(Metadata[Index].IsDeallocated, IsDeallocated);
91 checkBacktrace(Meta, IsDeallocated);
93 if (!IsDeallocated)
94 return;
96 EXPECT_EQ(Metadata[Index].DeallocationTrace.ThreadID,
97 __gwp_asan_get_deallocation_thread_id(Meta));
100 static constexpr size_t kNumBacktraceConstants = 4;
101 static uintptr_t BacktraceConstants[kNumBacktraceConstants];
102 AllocatorState State = {};
103 AllocationMetadata Metadata[4] = {};
104 uintptr_t InternalFaultAddr;
107 uintptr_t CrashHandlerAPITest::BacktraceConstants[kNumBacktraceConstants] = {
108 0xdeadbeef, 0xdeadc0de, 0xbadc0ffe, 0xcafef00d};
110 TEST_F(CrashHandlerAPITest, PointerNotMine) {
111 uintptr_t UnknownPtr = reinterpret_cast<uintptr_t>(&State);
113 EXPECT_FALSE(__gwp_asan_error_is_mine(&State, 0));
114 EXPECT_FALSE(__gwp_asan_error_is_mine(&State, UnknownPtr));
116 EXPECT_EQ(Error::UNKNOWN, __gwp_asan_diagnose_error(&State, Metadata, 0));
117 EXPECT_EQ(Error::UNKNOWN,
118 __gwp_asan_diagnose_error(&State, Metadata, UnknownPtr));
120 EXPECT_EQ(nullptr, __gwp_asan_get_metadata(&State, Metadata, 0));
121 EXPECT_EQ(nullptr, __gwp_asan_get_metadata(&State, Metadata, UnknownPtr));
124 TEST_F(CrashHandlerAPITest, PointerNotAllocated) {
125 uintptr_t FailureAddress = 0x9000;
127 EXPECT_TRUE(__gwp_asan_error_is_mine(&State, FailureAddress));
128 EXPECT_EQ(Error::UNKNOWN,
129 __gwp_asan_diagnose_error(&State, Metadata, FailureAddress));
130 EXPECT_EQ(0u, __gwp_asan_get_internal_crash_address(&State, FailureAddress));
131 EXPECT_EQ(nullptr, __gwp_asan_get_metadata(&State, Metadata, FailureAddress));
134 TEST_F(CrashHandlerAPITest, DoubleFree) {
135 size_t Index =
136 metadata(/* Addr */ 0x7000, /* Size */ 0x20, /* IsDeallocated */ true);
137 uintptr_t FailureAddress = 0x7000;
139 State.FailureType = Error::DOUBLE_FREE;
140 State.FailureAddress = FailureAddress;
142 EXPECT_TRUE(__gwp_asan_error_is_mine(&State));
143 EXPECT_EQ(Error::DOUBLE_FREE,
144 __gwp_asan_diagnose_error(&State, Metadata, 0x0));
145 EXPECT_EQ(FailureAddress,
146 __gwp_asan_get_internal_crash_address(&State, InternalFaultAddr));
147 checkMetadata(Index, FailureAddress);
150 TEST_F(CrashHandlerAPITest, InvalidFree) {
151 size_t Index =
152 metadata(/* Addr */ 0x7000, /* Size */ 0x20, /* IsDeallocated */ false);
153 uintptr_t FailureAddress = 0x7001;
155 State.FailureType = Error::INVALID_FREE;
156 State.FailureAddress = FailureAddress;
158 EXPECT_TRUE(__gwp_asan_error_is_mine(&State));
159 EXPECT_EQ(Error::INVALID_FREE,
160 __gwp_asan_diagnose_error(&State, Metadata, 0x0));
161 EXPECT_EQ(FailureAddress,
162 __gwp_asan_get_internal_crash_address(&State, InternalFaultAddr));
163 checkMetadata(Index, FailureAddress);
166 TEST_F(CrashHandlerAPITest, InvalidFreeNoMetadata) {
167 uintptr_t FailureAddress = 0x7001;
169 State.FailureType = Error::INVALID_FREE;
170 State.FailureAddress = FailureAddress;
172 EXPECT_TRUE(__gwp_asan_error_is_mine(&State));
173 EXPECT_EQ(Error::INVALID_FREE,
174 __gwp_asan_diagnose_error(&State, Metadata, 0x0));
175 EXPECT_EQ(FailureAddress,
176 __gwp_asan_get_internal_crash_address(&State, InternalFaultAddr));
177 EXPECT_EQ(nullptr, __gwp_asan_get_metadata(&State, Metadata, FailureAddress));
180 TEST_F(CrashHandlerAPITest, UseAfterFree) {
181 size_t Index =
182 metadata(/* Addr */ 0x7000, /* Size */ 0x20, /* IsDeallocated */ true);
183 uintptr_t FailureAddress = 0x7001;
185 EXPECT_TRUE(__gwp_asan_error_is_mine(&State, FailureAddress));
186 EXPECT_EQ(Error::USE_AFTER_FREE,
187 __gwp_asan_diagnose_error(&State, Metadata, FailureAddress));
188 EXPECT_EQ(0u, __gwp_asan_get_internal_crash_address(&State, FailureAddress));
189 checkMetadata(Index, FailureAddress);
192 TEST_F(CrashHandlerAPITest, BufferOverflow) {
193 size_t Index =
194 metadata(/* Addr */ 0x5f00, /* Size */ 0x100, /* IsDeallocated */ false);
195 uintptr_t FailureAddress = 0x6000;
197 EXPECT_TRUE(__gwp_asan_error_is_mine(&State, FailureAddress));
198 EXPECT_EQ(Error::BUFFER_OVERFLOW,
199 __gwp_asan_diagnose_error(&State, Metadata, FailureAddress));
200 EXPECT_EQ(0u, __gwp_asan_get_internal_crash_address(&State, FailureAddress));
201 checkMetadata(Index, FailureAddress);
204 TEST_F(CrashHandlerAPITest, BufferUnderflow) {
205 size_t Index =
206 metadata(/* Addr */ 0x3000, /* Size */ 0x10, /* IsDeallocated*/ false);
207 uintptr_t FailureAddress = 0x2fff;
209 EXPECT_TRUE(__gwp_asan_error_is_mine(&State, FailureAddress));
210 EXPECT_EQ(Error::BUFFER_UNDERFLOW,
211 __gwp_asan_diagnose_error(&State, Metadata, FailureAddress));
212 EXPECT_EQ(0u, __gwp_asan_get_internal_crash_address(&State, FailureAddress));
213 checkMetadata(Index, FailureAddress);