sanitizer_symbolizer.h 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. //===-- sanitizer_symbolizer.h ----------------------------------*- 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-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // Symbolizer is used by sanitizers to map instruction address to a location in
  10. // source code at run-time. Symbolizer either uses __sanitizer_symbolize_*
  11. // defined in the program, or (if they are missing) tries to find and
  12. // launch "llvm-symbolizer" commandline tool in a separate process and
  13. // communicate with it.
  14. //
  15. // Generally we should try to avoid calling system library functions during
  16. // symbolization (and use their replacements from sanitizer_libc.h instead).
  17. //===----------------------------------------------------------------------===//
  18. #ifndef SANITIZER_SYMBOLIZER_H
  19. #define SANITIZER_SYMBOLIZER_H
  20. #include "sanitizer_common.h"
  21. #include "sanitizer_mutex.h"
  22. #include "sanitizer_vector.h"
  23. namespace __sanitizer {
  24. struct AddressInfo {
  25. // Owns all the string members. Storage for them is
  26. // (de)allocated using sanitizer internal allocator.
  27. uptr address;
  28. char *module;
  29. uptr module_offset;
  30. ModuleArch module_arch;
  31. static const uptr kUnknown = ~(uptr)0;
  32. char *function;
  33. uptr function_offset;
  34. char *file;
  35. int line;
  36. int column;
  37. AddressInfo();
  38. // Deletes all strings and resets all fields.
  39. void Clear();
  40. void FillModuleInfo(const char *mod_name, uptr mod_offset, ModuleArch arch);
  41. };
  42. // Linked list of symbolized frames (each frame is described by AddressInfo).
  43. struct SymbolizedStack {
  44. SymbolizedStack *next;
  45. AddressInfo info;
  46. static SymbolizedStack *New(uptr addr);
  47. // Deletes current, and all subsequent frames in the linked list.
  48. // The object cannot be accessed after the call to this function.
  49. void ClearAll();
  50. private:
  51. SymbolizedStack();
  52. };
  53. // For now, DataInfo is used to describe global variable.
  54. struct DataInfo {
  55. // Owns all the string members. Storage for them is
  56. // (de)allocated using sanitizer internal allocator.
  57. char *module;
  58. uptr module_offset;
  59. ModuleArch module_arch;
  60. char *file;
  61. uptr line;
  62. char *name;
  63. uptr start;
  64. uptr size;
  65. DataInfo();
  66. void Clear();
  67. };
  68. struct LocalInfo {
  69. char *function_name = nullptr;
  70. char *name = nullptr;
  71. char *decl_file = nullptr;
  72. unsigned decl_line = 0;
  73. bool has_frame_offset = false;
  74. bool has_size = false;
  75. bool has_tag_offset = false;
  76. sptr frame_offset;
  77. uptr size;
  78. uptr tag_offset;
  79. void Clear();
  80. };
  81. struct FrameInfo {
  82. char *module;
  83. uptr module_offset;
  84. ModuleArch module_arch;
  85. InternalMmapVector<LocalInfo> locals;
  86. void Clear();
  87. };
  88. class SymbolizerTool;
  89. class Symbolizer final {
  90. public:
  91. /// Initialize and return platform-specific implementation of symbolizer
  92. /// (if it wasn't already initialized).
  93. static Symbolizer *GetOrInit();
  94. static void LateInitialize();
  95. // Returns a list of symbolized frames for a given address (containing
  96. // all inlined functions, if necessary).
  97. SymbolizedStack *SymbolizePC(uptr address);
  98. bool SymbolizeData(uptr address, DataInfo *info);
  99. bool SymbolizeFrame(uptr address, FrameInfo *info);
  100. // The module names Symbolizer returns are stable and unique for every given
  101. // module. It is safe to store and compare them as pointers.
  102. bool GetModuleNameAndOffsetForPC(uptr pc, const char **module_name,
  103. uptr *module_address);
  104. const char *GetModuleNameForPc(uptr pc) {
  105. const char *module_name = nullptr;
  106. uptr unused;
  107. if (GetModuleNameAndOffsetForPC(pc, &module_name, &unused))
  108. return module_name;
  109. return nullptr;
  110. }
  111. // Release internal caches (if any).
  112. void Flush();
  113. // Attempts to demangle the provided C++ mangled name.
  114. const char *Demangle(const char *name);
  115. // Allow user to install hooks that would be called before/after Symbolizer
  116. // does the actual file/line info fetching. Specific sanitizers may need this
  117. // to distinguish system library calls made in user code from calls made
  118. // during in-process symbolization.
  119. typedef void (*StartSymbolizationHook)();
  120. typedef void (*EndSymbolizationHook)();
  121. // May be called at most once.
  122. void AddHooks(StartSymbolizationHook start_hook,
  123. EndSymbolizationHook end_hook);
  124. void RefreshModules();
  125. const LoadedModule *FindModuleForAddress(uptr address);
  126. void InvalidateModuleList();
  127. private:
  128. // GetModuleNameAndOffsetForPC has to return a string to the caller.
  129. // Since the corresponding module might get unloaded later, we should create
  130. // our owned copies of the strings that we can safely return.
  131. // ModuleNameOwner does not provide any synchronization, thus calls to
  132. // its method should be protected by |mu_|.
  133. class ModuleNameOwner {
  134. public:
  135. explicit ModuleNameOwner(Mutex *synchronized_by)
  136. : last_match_(nullptr), mu_(synchronized_by) {
  137. storage_.reserve(kInitialCapacity);
  138. }
  139. const char *GetOwnedCopy(const char *str);
  140. private:
  141. static const uptr kInitialCapacity = 1000;
  142. InternalMmapVector<const char*> storage_;
  143. const char *last_match_;
  144. Mutex *mu_;
  145. } module_names_;
  146. /// Platform-specific function for creating a Symbolizer object.
  147. static Symbolizer *PlatformInit();
  148. bool FindModuleNameAndOffsetForAddress(uptr address, const char **module_name,
  149. uptr *module_offset,
  150. ModuleArch *module_arch);
  151. ListOfModules modules_;
  152. ListOfModules fallback_modules_;
  153. // If stale, need to reload the modules before looking up addresses.
  154. bool modules_fresh_;
  155. // Platform-specific default demangler, must not return nullptr.
  156. const char *PlatformDemangle(const char *name);
  157. static Symbolizer *symbolizer_;
  158. static StaticSpinMutex init_mu_;
  159. // Mutex locked from public methods of |Symbolizer|, so that the internals
  160. // (including individual symbolizer tools and platform-specific methods) are
  161. // always synchronized.
  162. Mutex mu_;
  163. IntrusiveList<SymbolizerTool> tools_;
  164. explicit Symbolizer(IntrusiveList<SymbolizerTool> tools);
  165. static LowLevelAllocator symbolizer_allocator_;
  166. StartSymbolizationHook start_hook_;
  167. EndSymbolizationHook end_hook_;
  168. class SymbolizerScope {
  169. public:
  170. explicit SymbolizerScope(const Symbolizer *sym);
  171. ~SymbolizerScope();
  172. private:
  173. const Symbolizer *sym_;
  174. };
  175. // Calls `LateInitialize()` on all items in `tools_`.
  176. void LateInitializeTools();
  177. };
  178. #ifdef SANITIZER_WINDOWS
  179. void InitializeDbgHelpIfNeeded();
  180. #endif
  181. } // namespace __sanitizer
  182. #endif // SANITIZER_SYMBOLIZER_H