143 lines · c
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-exception6//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_MACROS16#define ZXTEST_USE_STREAMABLE_MACROS17#endif18#include <zxtest/zxtest.h>19namespace testing = zxtest;20// zxtest defines a different ASSERT_DEATH, taking a lambda and an error message21// if death didn't occur, versus gtest taking a statement and a string to search22// for in the dying process. zxtest doesn't define an EXPECT_DEATH, so we use23// that in the tests below (which works as intended for gtest), and we define24// EXPECT_DEATH as a wrapper for zxtest's ASSERT_DEATH. Note that zxtest drops25// the functionality for checking for a particular message in death.26#define EXPECT_DEATH(X, Y) ASSERT_DEATH(([&] { X; }), "")27#else28#include "gtest/gtest.h"29#endif30 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 37namespace gwp_asan {38namespace test {39// This printf-function getter allows other platforms (e.g. Android) to define40// their own signal-safe Printf function. In LLVM, we use41// `optional/printf_sanitizer_common.cpp` which supplies the __sanitizer::Printf42// for this purpose.43Printf_t getPrintfFunction();44}; // namespace test45}; // namespace gwp_asan46 47char *AllocateMemory(gwp_asan::GuardedPoolAllocator &GPA);48void DeallocateMemory(gwp_asan::GuardedPoolAllocator &GPA, void *Ptr);49void DeallocateMemory2(gwp_asan::GuardedPoolAllocator &GPA, void *Ptr);50void TouchMemory(void *Ptr);51 52void CheckOnlyOneGwpAsanCrash(const std::string &OutputBuffer);53 54class DefaultGuardedPoolAllocator : public ::testing::Test {55public: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 64protected:65 gwp_asan::GuardedPoolAllocator GPA;66 decltype(gwp_asan::options::Options::MaxSimultaneousAllocations)67 MaxSimultaneousAllocations;68};69 70class CustomGuardedPoolAllocator : public ::testing::Test {71public:72 void73 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 83protected:84 gwp_asan::GuardedPoolAllocator GPA;85 decltype(gwp_asan::options::Options::MaxSimultaneousAllocations)86 MaxSimultaneousAllocations;87};88 89class BacktraceGuardedPoolAllocator90 : public ::testing::TestWithParam</* Recoverable */ bool> {91public: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 that98 // we can search it in unit tests. For non-recoverable tests, the default99 // 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 117protected:118 static std::string &GetOutputBuffer() {119 static std::string Buffer;120 return Buffer;121 }122 123 __attribute__((format(printf, 1, 2))) static void124 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-threads138using DefaultGuardedPoolAllocatorDeathTest = DefaultGuardedPoolAllocator;139using CustomGuardedPoolAllocatorDeathTest = CustomGuardedPoolAllocator;140using BacktraceGuardedPoolAllocatorDeathTest = BacktraceGuardedPoolAllocator;141 142#endif // GWP_ASAN_TESTS_HARNESS_H_143