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