[clang] Handle __declspec() attributes in using
[llvm-project.git] / compiler-rt / lib / gwp_asan / tests / backtrace.cpp
blobe878994396254e83a20cb1fa7ac1c956b0386931
1 //===-- backtrace.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 <regex>
10 #include <string>
12 #include "gwp_asan/common.h"
13 #include "gwp_asan/crash_handler.h"
14 #include "gwp_asan/tests/harness.h"
16 TEST_P(BacktraceGuardedPoolAllocatorDeathTest, DoubleFree) {
17 void *Ptr = AllocateMemory(GPA);
18 DeallocateMemory(GPA, Ptr);
20 std::string DeathRegex = "Double Free.*DeallocateMemory2.*";
21 DeathRegex.append("was deallocated.*DeallocateMemory[^2].*");
22 DeathRegex.append("was allocated.*AllocateMemory");
23 if (!Recoverable) {
24 ASSERT_DEATH(DeallocateMemory2(GPA, Ptr), DeathRegex);
25 return;
28 // For recoverable, assert that DeallocateMemory2() doesn't crash.
29 DeallocateMemory2(GPA, Ptr);
30 // Fuchsia's zxtest doesn't have an EXPECT_THAT(testing::MatchesRegex(), ...),
31 // so check the regex manually.
32 EXPECT_TRUE(std::regex_search(
33 GetOutputBuffer(),
34 std::basic_regex(DeathRegex, std::regex_constants::extended)))
35 << "Regex \"" << DeathRegex
36 << "\" was not found in input:\n============\n"
37 << GetOutputBuffer() << "\n============";
40 TEST_P(BacktraceGuardedPoolAllocatorDeathTest, UseAfterFree) {
41 #if defined(__linux__) && __ARM_ARCH == 7
42 // Incomplete backtrace on Armv7 Linux
43 GTEST_SKIP();
44 #endif
46 void *Ptr = AllocateMemory(GPA);
47 DeallocateMemory(GPA, Ptr);
49 std::string DeathRegex = "Use After Free.*TouchMemory.*";
50 DeathRegex.append("was deallocated.*DeallocateMemory[^2].*");
51 DeathRegex.append("was allocated.*AllocateMemory");
53 if (!Recoverable) {
54 ASSERT_DEATH(TouchMemory(Ptr), DeathRegex);
55 return;
58 // For recoverable, assert that TouchMemory() doesn't crash.
59 TouchMemory(Ptr);
60 // Fuchsia's zxtest doesn't have an EXPECT_THAT(testing::MatchesRegex(), ...),
61 // so check the regex manually.
62 EXPECT_TRUE(std::regex_search(
63 GetOutputBuffer(),
64 std::basic_regex(DeathRegex, std::regex_constants::extended)))
65 << "Regex \"" << DeathRegex
66 << "\" was not found in input:\n============\n"
67 << GetOutputBuffer() << "\n============";
71 INSTANTIATE_TEST_SUITE_P(RecoverableSignalDeathTest,
72 BacktraceGuardedPoolAllocatorDeathTest,
73 /* Recoverable */ testing::Bool());
75 TEST(Backtrace, Short) {
76 gwp_asan::AllocationMetadata Meta;
77 Meta.AllocationTrace.RecordBacktrace(
78 [](uintptr_t *TraceBuffer, size_t /* Size */) -> size_t {
79 TraceBuffer[0] = 123u;
80 TraceBuffer[1] = 321u;
81 return 2u;
82 });
83 uintptr_t TraceOutput[2] = {};
84 EXPECT_EQ(2u, __gwp_asan_get_allocation_trace(&Meta, TraceOutput, 2));
85 EXPECT_EQ(TraceOutput[0], 123u);
86 EXPECT_EQ(TraceOutput[1], 321u);
89 TEST(Backtrace, ExceedsStorableLength) {
90 gwp_asan::AllocationMetadata Meta;
91 Meta.AllocationTrace.RecordBacktrace(
92 [](uintptr_t *TraceBuffer, size_t Size) -> size_t {
93 // Need to inintialise the elements that will be packed.
94 memset(TraceBuffer, 0u, Size * sizeof(*TraceBuffer));
96 // Indicate that there were more frames, and we just didn't have enough
97 // room to store them.
98 return Size * 2;
99 });
100 // Retrieve a frame from the collected backtrace, make sure it works E2E.
101 uintptr_t TraceOutput;
102 EXPECT_EQ(gwp_asan::AllocationMetadata::kMaxTraceLengthToCollect,
103 __gwp_asan_get_allocation_trace(&Meta, &TraceOutput, 1));
106 TEST(Backtrace, ExceedsRetrievableAllocLength) {
107 gwp_asan::AllocationMetadata Meta;
108 constexpr size_t kNumFramesToStore = 3u;
109 Meta.AllocationTrace.RecordBacktrace(
110 [](uintptr_t *TraceBuffer, size_t /* Size */) -> size_t {
111 memset(TraceBuffer, kNumFramesToStore,
112 kNumFramesToStore * sizeof(*TraceBuffer));
113 return kNumFramesToStore;
115 uintptr_t TraceOutput;
116 // Ask for one element, get told that there's `kNumFramesToStore` available.
117 EXPECT_EQ(kNumFramesToStore,
118 __gwp_asan_get_allocation_trace(&Meta, &TraceOutput, 1));
121 TEST(Backtrace, ExceedsRetrievableDeallocLength) {
122 gwp_asan::AllocationMetadata Meta;
123 constexpr size_t kNumFramesToStore = 3u;
124 Meta.DeallocationTrace.RecordBacktrace(
125 [](uintptr_t *TraceBuffer, size_t /* Size */) -> size_t {
126 memset(TraceBuffer, kNumFramesToStore,
127 kNumFramesToStore * sizeof(*TraceBuffer));
128 return kNumFramesToStore;
130 uintptr_t TraceOutput;
131 // Ask for one element, get told that there's `kNumFramesToStore` available.
132 EXPECT_EQ(kNumFramesToStore,
133 __gwp_asan_get_deallocation_trace(&Meta, &TraceOutput, 1));