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 43 // First call returns true, all the following calls return false. 44 bool OnlyOnce(); 45 46 }; // namespace test 47 }; // namespace gwp_asan 48 49 char *AllocateMemory(gwp_asan::GuardedPoolAllocator &GPA); 50 void DeallocateMemory(gwp_asan::GuardedPoolAllocator &GPA, void *Ptr); 51 void DeallocateMemory2(gwp_asan::GuardedPoolAllocator &GPA, void *Ptr); 52 void TouchMemory(void *Ptr); 53 54 void CheckOnlyOneGwpAsanCrash(const std::string &OutputBuffer); 55 56 class DefaultGuardedPoolAllocator : public ::testing::Test { 57 public: SetUp()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 TearDown()67 void TearDown() override { GPA.uninitTestOnly(); } 68 69 protected: 70 gwp_asan::GuardedPoolAllocator GPA; 71 decltype(gwp_asan::options::Options::MaxSimultaneousAllocations) 72 MaxSimultaneousAllocations; 73 }; 74 75 class CustomGuardedPoolAllocator : public ::testing::Test { 76 public: 77 void InitNumSlots(decltype (gwp_asan::options::Options::MaxSimultaneousAllocations)MaxSimultaneousAllocationsArg)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 TearDown()90 void TearDown() override { GPA.uninitTestOnly(); } 91 92 protected: 93 gwp_asan::GuardedPoolAllocator GPA; 94 decltype(gwp_asan::options::Options::MaxSimultaneousAllocations) 95 MaxSimultaneousAllocations; 96 }; 97 98 class BacktraceGuardedPoolAllocator 99 : public ::testing::TestWithParam</* Recoverable */ bool> { 100 public: SetUp()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, PrintfFunction, gwp_asan::backtrace::getPrintBacktraceFunction(), 120 gwp_asan::backtrace::getSegvBacktraceFunction(), 121 /* Recoverable */ Recoverable); 122 } 123 TearDown()124 void TearDown() override { 125 GPA.uninitTestOnly(); 126 gwp_asan::segv_handler::uninstallSignalHandlers(); 127 } 128 129 protected: GetOutputBuffer()130 static std::string &GetOutputBuffer() { 131 static std::string Buffer; 132 return Buffer; 133 } 134 135 __attribute__((format(printf, 1, 2))) static void PrintfToBuffer(const char * Format,...)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 150 using DefaultGuardedPoolAllocatorDeathTest = DefaultGuardedPoolAllocator; 151 using CustomGuardedPoolAllocatorDeathTest = CustomGuardedPoolAllocator; 152 using BacktraceGuardedPoolAllocatorDeathTest = BacktraceGuardedPoolAllocator; 153 154 #endif // GWP_ASAN_TESTS_HARNESS_H_ 155