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>
17namespace 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
35namespace gwp_asan {
36namespace 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.
41Printf_t getPrintfFunction();
42
43// First call returns true, all the following calls return false.
44bool OnlyOnce();
45
46}; // namespace test
47}; // namespace gwp_asan
48
49char *AllocateMemory(gwp_asan::GuardedPoolAllocator &GPA);
50void DeallocateMemory(gwp_asan::GuardedPoolAllocator &GPA, void *Ptr);
51void DeallocateMemory2(gwp_asan::GuardedPoolAllocator &GPA, void *Ptr);
52void TouchMemory(void *Ptr);
53
54void CheckOnlyOneGwpAsanCrash(const std::string &OutputBuffer);
55
56class DefaultGuardedPoolAllocator : public ::testing::Test {
57public:
58 void SetUp() override {
59 gwp_asan::options::Options Opts;
60 Opts.setDefaults();
61 MaxSimultaneousAllocations = Opts.MaxSimultaneousAllocations;
62
63 Opts.InstallForkHandlers = gwp_asan::test::OnlyOnce();
64 GPA.init(Opts);
65 }
66
67 void TearDown() override { GPA.uninitTestOnly(); }
68
69protected:
70 gwp_asan::GuardedPoolAllocator GPA;
71 decltype(gwp_asan::options::Options::MaxSimultaneousAllocations)
72 MaxSimultaneousAllocations;
73};
74
75class CustomGuardedPoolAllocator : public ::testing::Test {
76public:
77 void
78 InitNumSlots(decltype(gwp_asan::options::Options::MaxSimultaneousAllocations)
79 MaxSimultaneousAllocationsArg) {
80 gwp_asan::options::Options Opts;
81 Opts.setDefaults();
82
83 Opts.MaxSimultaneousAllocations = MaxSimultaneousAllocationsArg;
84 MaxSimultaneousAllocations = MaxSimultaneousAllocationsArg;
85
86 Opts.InstallForkHandlers = gwp_asan::test::OnlyOnce();
87 GPA.init(Opts);
88 }
89
90 void TearDown() override { GPA.uninitTestOnly(); }
91
92protected:
93 gwp_asan::GuardedPoolAllocator GPA;
94 decltype(gwp_asan::options::Options::MaxSimultaneousAllocations)
95 MaxSimultaneousAllocations;
96};
97
98class BacktraceGuardedPoolAllocator
99 : public ::testing::TestWithParam</* Recoverable */ bool> {
100public:
101 void SetUp() override {
102 gwp_asan::options::Options Opts;
103 Opts.setDefaults();
104
105 Opts.Backtrace = gwp_asan::backtrace::getBacktraceFunction();
106 Opts.InstallForkHandlers = gwp_asan::test::OnlyOnce();
107 GPA.init(Opts);
108
109 // In recoverable mode, capture GWP-ASan logs to an internal buffer so that
110 // we can search it in unit tests. For non-recoverable tests, the default
111 // buffer is fine, as any tests should be EXPECT_DEATH()'d.
112 Recoverable = GetParam();
113 gwp_asan::Printf_t PrintfFunction = PrintfToBuffer;
114 GetOutputBuffer().clear();
115 if (!Recoverable)
116 PrintfFunction = gwp_asan::test::getPrintfFunction();
117
118 gwp_asan::segv_handler::installSignalHandlers(
119 GPA: &GPA, Printf: PrintfFunction, PrintBacktrace: gwp_asan::backtrace::getPrintBacktraceFunction(),
120 SegvBacktrace: gwp_asan::backtrace::getSegvBacktraceFunction(),
121 /* Recoverable */ Recoverable);
122 }
123
124 void TearDown() override {
125 GPA.uninitTestOnly();
126 gwp_asan::segv_handler::uninstallSignalHandlers();
127 }
128
129protected:
130 static std::string &GetOutputBuffer() {
131 static std::string Buffer;
132 return Buffer;
133 }
134
135 __attribute__((format(printf, 1, 2))) static void
136 PrintfToBuffer(const char *Format, ...) {
137 va_list AP;
138 va_start(AP, Format);
139 char Buffer[8192];
140 vsnprintf(Buffer, sizeof(Buffer), Format, AP);
141 GetOutputBuffer() += Buffer;
142 va_end(AP);
143 }
144
145 gwp_asan::GuardedPoolAllocator GPA;
146 bool Recoverable;
147};
148
149// https://github.com/google/googletest/blob/master/docs/advanced.md#death-tests-and-threads
150using DefaultGuardedPoolAllocatorDeathTest = DefaultGuardedPoolAllocator;
151using CustomGuardedPoolAllocatorDeathTest = CustomGuardedPoolAllocator;
152using BacktraceGuardedPoolAllocatorDeathTest = BacktraceGuardedPoolAllocator;
153
154#endif // GWP_ASAN_TESTS_HARNESS_H_
155

source code of compiler-rt/lib/gwp_asan/tests/harness.h