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