sanitizer_symbolizer.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. //===-- sanitizer_symbolizer.cpp ------------------------------------------===//
  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. // This file is shared between AddressSanitizer and ThreadSanitizer
  10. // run-time libraries.
  11. //===----------------------------------------------------------------------===//
  12. #include "sanitizer_allocator_internal.h"
  13. #include "sanitizer_common.h"
  14. #include "sanitizer_internal_defs.h"
  15. #include "sanitizer_libc.h"
  16. #include "sanitizer_placement_new.h"
  17. #include "sanitizer_platform.h"
  18. #include "sanitizer_symbolizer_internal.h"
  19. namespace __sanitizer {
  20. AddressInfo::AddressInfo() {
  21. internal_memset(this, 0, sizeof(AddressInfo));
  22. function_offset = kUnknown;
  23. }
  24. void AddressInfo::Clear() {
  25. InternalFree(module);
  26. InternalFree(function);
  27. InternalFree(file);
  28. internal_memset(this, 0, sizeof(AddressInfo));
  29. function_offset = kUnknown;
  30. uuid_size = 0;
  31. }
  32. void AddressInfo::FillModuleInfo(const char *mod_name, uptr mod_offset,
  33. ModuleArch mod_arch) {
  34. module = internal_strdup(mod_name);
  35. module_offset = mod_offset;
  36. module_arch = mod_arch;
  37. uuid_size = 0;
  38. }
  39. void AddressInfo::FillModuleInfo(const LoadedModule &mod) {
  40. module = internal_strdup(mod.full_name());
  41. module_offset = address - mod.base_address();
  42. module_arch = mod.arch();
  43. if (mod.uuid_size())
  44. internal_memcpy(uuid, mod.uuid(), mod.uuid_size());
  45. uuid_size = mod.uuid_size();
  46. }
  47. SymbolizedStack::SymbolizedStack() : next(nullptr), info() {}
  48. SymbolizedStack *SymbolizedStack::New(uptr addr) {
  49. void *mem = InternalAlloc(sizeof(SymbolizedStack));
  50. SymbolizedStack *res = new(mem) SymbolizedStack();
  51. res->info.address = addr;
  52. return res;
  53. }
  54. void SymbolizedStack::ClearAll() {
  55. info.Clear();
  56. if (next)
  57. next->ClearAll();
  58. InternalFree(this);
  59. }
  60. DataInfo::DataInfo() {
  61. internal_memset(this, 0, sizeof(DataInfo));
  62. }
  63. void DataInfo::Clear() {
  64. InternalFree(module);
  65. InternalFree(file);
  66. InternalFree(name);
  67. internal_memset(this, 0, sizeof(DataInfo));
  68. }
  69. void FrameInfo::Clear() {
  70. InternalFree(module);
  71. for (LocalInfo &local : locals) {
  72. InternalFree(local.function_name);
  73. InternalFree(local.name);
  74. InternalFree(local.decl_file);
  75. }
  76. locals.clear();
  77. }
  78. Symbolizer *Symbolizer::symbolizer_;
  79. StaticSpinMutex Symbolizer::init_mu_;
  80. LowLevelAllocator Symbolizer::symbolizer_allocator_;
  81. void Symbolizer::InvalidateModuleList() {
  82. modules_fresh_ = false;
  83. }
  84. void Symbolizer::AddHooks(Symbolizer::StartSymbolizationHook start_hook,
  85. Symbolizer::EndSymbolizationHook end_hook) {
  86. CHECK(start_hook_ == 0 && end_hook_ == 0);
  87. start_hook_ = start_hook;
  88. end_hook_ = end_hook;
  89. }
  90. const char *Symbolizer::ModuleNameOwner::GetOwnedCopy(const char *str) {
  91. mu_->CheckLocked();
  92. // 'str' will be the same string multiple times in a row, optimize this case.
  93. if (last_match_ && !internal_strcmp(last_match_, str))
  94. return last_match_;
  95. // FIXME: this is linear search.
  96. // We should optimize this further if this turns out to be a bottleneck later.
  97. for (uptr i = 0; i < storage_.size(); ++i) {
  98. if (!internal_strcmp(storage_[i], str)) {
  99. last_match_ = storage_[i];
  100. return last_match_;
  101. }
  102. }
  103. last_match_ = internal_strdup(str);
  104. storage_.push_back(last_match_);
  105. return last_match_;
  106. }
  107. Symbolizer::Symbolizer(IntrusiveList<SymbolizerTool> tools)
  108. : module_names_(&mu_), modules_(), modules_fresh_(false), tools_(tools),
  109. start_hook_(0), end_hook_(0) {}
  110. Symbolizer::SymbolizerScope::SymbolizerScope(const Symbolizer *sym)
  111. : sym_(sym) {
  112. if (sym_->start_hook_)
  113. sym_->start_hook_();
  114. }
  115. Symbolizer::SymbolizerScope::~SymbolizerScope() {
  116. if (sym_->end_hook_)
  117. sym_->end_hook_();
  118. }
  119. } // namespace __sanitizer