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