brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.7 KiB · e43f7a2 Raw
188 lines · cpp
1// RUN: %clangxx %s -o %t -g && %run %t 2>&1 | FileCheck %s2 3// REQUIRES: internal_symbolizer4 5#include <assert.h>6#include <dlfcn.h>7#include <link.h>8#include <sanitizer/hwasan_interface.h>9#include <sanitizer/msan_interface.h>10#include <string.h>11 12#include <string>13#include <vector>14 15extern "C" {16bool __sanitizer_symbolize_code(const char *ModuleName, uint64_t ModuleOffset,17                                char *Buffer, int MaxLength,18                                bool SymbolizeInlineFrames);19bool __sanitizer_symbolize_data(const char *ModuleName, uint64_t ModuleOffset,20                                char *Buffer, int MaxLength);21bool __sanitizer_symbolize_frame(const char *ModuleName, uint64_t ModuleOffset,22                                 char *Buffer, int MaxLength);23void __sanitizer_print_stack_trace();24bool __sanitizer_symbolize_demangle(const char *Name, char *Buffer,25                                    int MaxLength);26}27 28struct ScopedInSymbolizer {29#if defined(__has_feature)30#  if __has_feature(memory_sanitizer)31  ScopedInSymbolizer() { __msan_scoped_disable_interceptor_checks(); }32  ~ScopedInSymbolizer() { __msan_scoped_enable_interceptor_checks(); }33#  endif34#endif35};36 37struct FrameInfo {38  int line;39  std::string file;40  std::string function;41  void *address;42};43 44__attribute__((noinline)) void *GetPC() { return __builtin_return_address(0); }45 46__attribute__((always_inline)) FrameInfo InlineFunction() {47  void *address = GetPC();48  return {0, "", "",49          reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(address) - 1)};50}51 52__attribute__((noinline)) FrameInfo NoInlineFunction() {53  void *address = GetPC();54  return {0, "", "",55          reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(address) - 1)};56}57 58template <int N> struct A {59  template <class T> FrameInfo RecursiveTemplateFunction(const T &t);60};61 62template <int N>63template <class T>64__attribute__((noinline)) FrameInfo A<N>::RecursiveTemplateFunction(const T &) {65  std::vector<T> t;66  return A<N - 1>().RecursiveTemplateFunction(t);67}68 69template <>70template <class T>71__attribute__((noinline)) FrameInfo A<0>::RecursiveTemplateFunction(const T &) {72  return NoInlineFunction();73}74 75__attribute__((no_sanitize_memory)) std::pair<const char *, uint64_t>76GetModuleAndOffset(const void *address) {77  Dl_info di;78  link_map *lm = nullptr;79#if __has_feature(hwaddress_sanitizer)80  address = __hwasan_tag_pointer(address, 0);81#endif82  assert(83      dladdr1(address, &di, reinterpret_cast<void **>(&lm), RTLD_DL_LINKMAP));84  return {di.dli_fname, reinterpret_cast<uint64_t>(address) - lm->l_addr};85}86 87std::string Symbolize(FrameInfo frame) {88  auto modul_offset = GetModuleAndOffset(frame.address);89  char buffer[1024] = {};90  ScopedInSymbolizer in_symbolizer;91  assert(__sanitizer_symbolize_code(modul_offset.first, modul_offset.second,92                                    buffer, std::size(buffer), true));93  return buffer;94}95 96std::string GetRegex(const FrameInfo &frame) {97  return frame.function + "[^\\n]*\\n[^\\n]*" + frame.file + ":" +98         std::to_string(frame.line);99}100 101void TestInline() {102  auto frame = InlineFunction();103  fprintf(stderr, "%s: %s\n", __FUNCTION__, Symbolize(frame).c_str());104  // CHECK-LABEL: TestInline: InlineFunction()105  // CHECK-NEXT: internal_symbolizer.cpp:[[# @LINE - 58]]106  // CHECK-NEXT: TestInline()107  // CHECK-NEXT: internal_symbolizer.cpp:[[# @LINE - 5]]108}109 110void TestNoInline() {111  auto frame = NoInlineFunction();112  fprintf(stderr, "%s: %s\n", __FUNCTION__, Symbolize(frame).c_str());113  // CHECK-LABEL: TestNoInline: NoInlineFunction()114  // CHECK-NEXT: internal_symbolizer.cpp:[[# @LINE - 61]]115}116 117void TestLongFunctionNames() {118  auto frame = A<10>().RecursiveTemplateFunction(0);119  fprintf(stderr, "%s: %s\n", __FUNCTION__, Symbolize(frame).c_str());120  // CHECK-LABEL: TestLongFunctionNames: NoInlineFunction()121  // CHECK-NEXT: internal_symbolizer.cpp:[[# @LINE - 68]]122}123 124std::string SymbolizeStaticVar() {125  static int var = 1;126  auto modul_offset = GetModuleAndOffset(&var);127  char buffer[1024] = {};128  ScopedInSymbolizer in_symbolizer;129  assert(__sanitizer_symbolize_data(modul_offset.first, modul_offset.second,130                                    buffer, std::size(buffer)));131  return buffer;132}133 134void TestData() {135  fprintf(stderr, "%s: %s\n", __FUNCTION__, SymbolizeStaticVar().c_str());136  // CHECK-LABEL: TestData: SymbolizeStaticVar[abi:cxx11]()::var137  // CHECK-NEXT: {{[0-9]+ +[0-9]+}}138  // CHECK-NEXT: internal_symbolizer.cpp:[[# @LINE - 13]]139}140 141__attribute__((noinline)) std::string SymbolizeLocalVars(const void *pc) {142  auto modul_offset = GetModuleAndOffset(pc);143  char buffer[1024] = {};144  ScopedInSymbolizer in_symbolizer;145  __sanitizer_symbolize_frame(modul_offset.first, modul_offset.second, buffer,146                              std::size(buffer));147  return buffer;148}149 150__attribute__((151    noinline,152    no_sanitize_address /* Asan merges allocas destroying variable DI */)) void153TestFrame() {154  volatile int var = 1;155  void *address = GetPC();156  fprintf(stderr, "%s: %s\n", __FUNCTION__,157          SymbolizeLocalVars(address).c_str());158  // CHECK-LABEL: TestFrame: TestFrame159  // CHECK-NEXT: var160  // CHECK-NEXT: internal_symbolizer.cpp:[[# @LINE - 6]]161  // CHECK-NEXT: {{-?[0-9]+ +[0-9]+}}162  // CHECK-NEXT: TestFrame163  // CHECK-NEXT: address164  // CHECK-NEXT: internal_symbolizer.cpp:[[# @LINE - 9]]165  // CHECK-NEXT: {{-?[0-9]+ +[0-9]+}}166}167 168void TestDemangle() {169  char out[128];170  assert(!__sanitizer_symbolize_demangle("1A", out, sizeof(out)));171 172  const char name[] = "_Z3fooi";173  for (int i = 1; i < sizeof(out); ++i) {174    memset(out, 1, sizeof(out));175    assert(__sanitizer_symbolize_demangle(name, out, i) == (i > 8));176    assert(i < 9 || 0 == strncmp(out, "foo(int)", i - 1));177  }178}179 180int main() {181  TestInline();182  TestNoInline();183  TestLongFunctionNames();184  TestData();185  TestFrame();186  TestDemangle();187}188