xref: /aosp_15_r20/external/gwp_asan/gwp_asan/tests/harness.h (revision b302aa5039729da396909ef03e815160dab4448c)
1 //===-- harness.h -----------------------------------------------*- 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 //===----------------------------------------------------------------------===//
8 
9 #ifndef GWP_ASAN_TESTS_HARNESS_H_
10 #define GWP_ASAN_TESTS_HARNESS_H_
11 
12 #include <stdarg.h>
13 
14 #if defined(__Fuchsia__)
15 #define ZXTEST_USE_STREAMABLE_MACROS
16 #include <zxtest/zxtest.h>
17 namespace testing = zxtest;
18 // zxtest defines a different ASSERT_DEATH, taking a lambda and an error message
19 // if death didn't occur, versus gtest taking a statement and a string to search
20 // for in the dying process. zxtest doesn't define an EXPECT_DEATH, so we use
21 // that in the tests below (which works as intended for gtest), and we define
22 // EXPECT_DEATH as a wrapper for zxtest's ASSERT_DEATH. Note that zxtest drops
23 // the functionality for checking for a particular message in death.
24 #define EXPECT_DEATH(X, Y) ASSERT_DEATH(([&] { X; }), "")
25 #else
26 #include "gtest/gtest.h"
27 #endif
28 
29 #include "gwp_asan/guarded_pool_allocator.h"
30 #include "gwp_asan/optional/backtrace.h"
31 #include "gwp_asan/optional/printf.h"
32 #include "gwp_asan/optional/segv_handler.h"
33 #include "gwp_asan/options.h"
34 
35 namespace gwp_asan {
36 namespace test {
37 // This printf-function getter allows other platforms (e.g. Android) to define
38 // their own signal-safe Printf function. In LLVM, we use
39 // `optional/printf_sanitizer_common.cpp` which supplies the __sanitizer::Printf
40 // for this purpose.
41 Printf_t getPrintfFunction();
42 }; // namespace test
43 }; // namespace gwp_asan
44 
45 char *AllocateMemory(gwp_asan::GuardedPoolAllocator &GPA);
46 void DeallocateMemory(gwp_asan::GuardedPoolAllocator &GPA, void *Ptr);
47 void DeallocateMemory2(gwp_asan::GuardedPoolAllocator &GPA, void *Ptr);
48 void TouchMemory(void *Ptr);
49 
50 void CheckOnlyOneGwpAsanCrash(const std::string &OutputBuffer);
51 
52 class DefaultGuardedPoolAllocator : public ::testing::Test {
53 public:
SetUp()54   void SetUp() override {
55     gwp_asan::options::Options Opts;
56     MaxSimultaneousAllocations = Opts.MaxSimultaneousAllocations;
57     GPA.init(Opts);
58   }
59 
TearDown()60   void TearDown() override { GPA.uninitTestOnly(); }
61 
62 protected:
63   gwp_asan::GuardedPoolAllocator GPA;
64   decltype(gwp_asan::options::Options::MaxSimultaneousAllocations)
65       MaxSimultaneousAllocations;
66 };
67 
68 class CustomGuardedPoolAllocator : public ::testing::Test {
69 public:
70   void
InitNumSlots(decltype (gwp_asan::options::Options::MaxSimultaneousAllocations)MaxSimultaneousAllocationsArg)71   InitNumSlots(decltype(gwp_asan::options::Options::MaxSimultaneousAllocations)
72                    MaxSimultaneousAllocationsArg) {
73     gwp_asan::options::Options Opts;
74     Opts.MaxSimultaneousAllocations = MaxSimultaneousAllocationsArg;
75     MaxSimultaneousAllocations = MaxSimultaneousAllocationsArg;
76     GPA.init(Opts);
77   }
78 
TearDown()79   void TearDown() override { GPA.uninitTestOnly(); }
80 
81 protected:
82   gwp_asan::GuardedPoolAllocator GPA;
83   decltype(gwp_asan::options::Options::MaxSimultaneousAllocations)
84       MaxSimultaneousAllocations;
85 };
86 
87 class BacktraceGuardedPoolAllocator
88     : public ::testing::TestWithParam</* Recoverable */ bool> {
89 public:
SetUp()90   void SetUp() override {
91     gwp_asan::options::Options Opts;
92     Opts.Backtrace = gwp_asan::backtrace::getBacktraceFunction();
93     GPA.init(Opts);
94 
95     // In recoverable mode, capture GWP-ASan logs to an internal buffer so that
96     // we can search it in unit tests. For non-recoverable tests, the default
97     // buffer is fine, as any tests should be EXPECT_DEATH()'d.
98     Recoverable = GetParam();
99     gwp_asan::Printf_t PrintfFunction = PrintfToBuffer;
100     GetOutputBuffer().clear();
101     if (!Recoverable)
102       PrintfFunction = gwp_asan::test::getPrintfFunction();
103 
104     gwp_asan::segv_handler::installSignalHandlers(
105         &GPA, PrintfFunction, gwp_asan::backtrace::getPrintBacktraceFunction(),
106         gwp_asan::backtrace::getSegvBacktraceFunction(),
107         /* Recoverable */ Recoverable);
108   }
109 
TearDown()110   void TearDown() override {
111     GPA.uninitTestOnly();
112     gwp_asan::segv_handler::uninstallSignalHandlers();
113   }
114 
115 protected:
GetOutputBuffer()116   static std::string &GetOutputBuffer() {
117     static std::string Buffer;
118     return Buffer;
119   }
120 
121   __attribute__((format(printf, 1, 2))) static void
PrintfToBuffer(const char * Format,...)122   PrintfToBuffer(const char *Format, ...) {
123     va_list AP;
124     va_start(AP, Format);
125     char Buffer[8192];
126     vsnprintf(Buffer, sizeof(Buffer), Format, AP);
127     GetOutputBuffer() += Buffer;
128     va_end(AP);
129   }
130 
131   gwp_asan::GuardedPoolAllocator GPA;
132   bool Recoverable;
133 };
134 
135 // https://github.com/google/googletest/blob/master/docs/advanced.md#death-tests-and-threads
136 using DefaultGuardedPoolAllocatorDeathTest = DefaultGuardedPoolAllocator;
137 using CustomGuardedPoolAllocatorDeathTest = CustomGuardedPoolAllocator;
138 using BacktraceGuardedPoolAllocatorDeathTest = BacktraceGuardedPoolAllocator;
139 
140 #endif // GWP_ASAN_TESTS_HARNESS_H_
141