brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.6 KiB · 6a84a2a Raw
131 lines · cpp
1//===-- backtrace.cpp -------------------------------------------*- 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#include <regex>10#include <string>11 12#include "gwp_asan/common.h"13#include "gwp_asan/crash_handler.h"14#include "gwp_asan/tests/harness.h"15 16TEST_P(BacktraceGuardedPoolAllocatorDeathTest, DoubleFree) {17  void *Ptr = AllocateMemory(GPA);18  DeallocateMemory(GPA, Ptr);19 20  std::string DeathRegex = "Double Free.*DeallocateMemory2.*";21  DeathRegex.append("was deallocated.*DeallocateMemory[^2].*");22  DeathRegex.append("was allocated.*AllocateMemory");23  if (!Recoverable) {24    EXPECT_DEATH(DeallocateMemory2(GPA, Ptr), DeathRegex);25    return;26  }27 28  // For recoverable, assert that DeallocateMemory2() doesn't crash.29  DeallocateMemory2(GPA, Ptr);30  // Fuchsia's zxtest doesn't have an EXPECT_THAT(testing::MatchesRegex(), ...),31  // so check the regex manually.32  EXPECT_TRUE(std::regex_search(33      GetOutputBuffer(),34      std::basic_regex(DeathRegex, std::regex_constants::extended)))35      << "Regex \"" << DeathRegex36      << "\" was not found in input:\n============\n"37      << GetOutputBuffer() << "\n============";38}39 40TEST_P(BacktraceGuardedPoolAllocatorDeathTest, UseAfterFree) {41#if defined(__linux__) && __ARM_ARCH == 742  // Incomplete backtrace on Armv7 Linux43  GTEST_SKIP();44#endif45 46  void *Ptr = AllocateMemory(GPA);47  DeallocateMemory(GPA, Ptr);48 49  std::string DeathRegex = "Use After Free.*TouchMemory.*";50  DeathRegex.append("was deallocated.*DeallocateMemory[^2].*");51  DeathRegex.append("was allocated.*AllocateMemory");52 53  if (!Recoverable) {54    EXPECT_DEATH(TouchMemory(Ptr), DeathRegex);55    return;56  }57 58  // For recoverable, assert that TouchMemory() doesn't crash.59  TouchMemory(Ptr);60  // Fuchsia's zxtest doesn't have an EXPECT_THAT(testing::MatchesRegex(), ...),61  // so check the regex manually.62  EXPECT_TRUE(std::regex_search(63      GetOutputBuffer(),64      std::basic_regex(DeathRegex, std::regex_constants::extended)))65      << "Regex \"" << DeathRegex66      << "\" was not found in input:\n============\n"67      << GetOutputBuffer() << "\n============";68  ;69}70 71TEST(Backtrace, Short) {72  gwp_asan::AllocationMetadata Meta;73  Meta.AllocationTrace.RecordBacktrace(74      [](uintptr_t *TraceBuffer, size_t /* Size */) -> size_t {75        TraceBuffer[0] = 123u;76        TraceBuffer[1] = 321u;77        return 2u;78      });79  uintptr_t TraceOutput[2] = {};80  EXPECT_EQ(2u, __gwp_asan_get_allocation_trace(&Meta, TraceOutput, 2));81  EXPECT_EQ(TraceOutput[0], 123u);82  EXPECT_EQ(TraceOutput[1], 321u);83}84 85TEST(Backtrace, ExceedsStorableLength) {86  gwp_asan::AllocationMetadata Meta;87  Meta.AllocationTrace.RecordBacktrace(88      [](uintptr_t *TraceBuffer, size_t Size) -> size_t {89        // Need to inintialise the elements that will be packed.90        memset(TraceBuffer, 0u, Size * sizeof(*TraceBuffer));91 92        // Indicate that there were more frames, and we just didn't have enough93        // room to store them.94        return Size * 2;95      });96  // Retrieve a frame from the collected backtrace, make sure it works E2E.97  uintptr_t TraceOutput;98  EXPECT_EQ(gwp_asan::AllocationMetadata::kMaxTraceLengthToCollect,99            __gwp_asan_get_allocation_trace(&Meta, &TraceOutput, 1));100}101 102TEST(Backtrace, ExceedsRetrievableAllocLength) {103  gwp_asan::AllocationMetadata Meta;104  constexpr size_t kNumFramesToStore = 3u;105  Meta.AllocationTrace.RecordBacktrace(106      [](uintptr_t *TraceBuffer, size_t /* Size */) -> size_t {107        memset(TraceBuffer, kNumFramesToStore,108               kNumFramesToStore * sizeof(*TraceBuffer));109        return kNumFramesToStore;110      });111  uintptr_t TraceOutput;112  // Ask for one element, get told that there's `kNumFramesToStore` available.113  EXPECT_EQ(kNumFramesToStore,114            __gwp_asan_get_allocation_trace(&Meta, &TraceOutput, 1));115}116 117TEST(Backtrace, ExceedsRetrievableDeallocLength) {118  gwp_asan::AllocationMetadata Meta;119  constexpr size_t kNumFramesToStore = 3u;120  Meta.DeallocationTrace.RecordBacktrace(121      [](uintptr_t *TraceBuffer, size_t /* Size */) -> size_t {122        memset(TraceBuffer, kNumFramesToStore,123               kNumFramesToStore * sizeof(*TraceBuffer));124        return kNumFramesToStore;125      });126  uintptr_t TraceOutput;127  // Ask for one element, get told that there's `kNumFramesToStore` available.128  EXPECT_EQ(kNumFramesToStore,129            __gwp_asan_get_deallocation_trace(&Meta, &TraceOutput, 1));130}131