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