sanitizer_symbolizer.cpp 3.9 KB

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