sanitizer_symbolizer.cpp 3.7 KB

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