sanitizer_symbolizer.h 6.7 KB

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