1 //===-- sanitizer_symbolizer.h ----------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // Symbolizer is used by sanitizers to map instruction address to a location in 11 // source code at run-time. Symbolizer either uses __sanitizer_symbolize_* 12 // defined in the program, or (if they are missing) tries to find and 13 // launch "llvm-symbolizer" commandline tool in a separate process and 14 // communicate with it. 15 // 16 // Generally we should try to avoid calling system library functions during 17 // symbolization (and use their replacements from sanitizer_libc.h instead). 18 //===----------------------------------------------------------------------===// 19 #ifndef SANITIZER_SYMBOLIZER_H 20 #define SANITIZER_SYMBOLIZER_H 21 22 #include "sanitizer_allocator_internal.h" 23 #include "sanitizer_internal_defs.h" 24 #include "sanitizer_libc.h" 25 26 namespace __sanitizer { 27 28 struct AddressInfo { 29 uptr address; 30 31 char *module; 32 uptr module_offset; 33 34 static const uptr kUnknown = ~(uptr)0; 35 char *function; 36 uptr function_offset; 37 38 char *file; 39 int line; 40 int column; 41 AddressInfoAddressInfo42 AddressInfo() { 43 internal_memset(this, 0, sizeof(AddressInfo)); 44 function_offset = kUnknown; 45 } 46 47 // Deletes all strings and resets all fields. ClearAddressInfo48 void Clear() { 49 InternalFree(module); 50 InternalFree(function); 51 InternalFree(file); 52 internal_memset(this, 0, sizeof(AddressInfo)); 53 function_offset = kUnknown; 54 } 55 FillAddressAndModuleInfoAddressInfo56 void FillAddressAndModuleInfo(uptr addr, const char *mod_name, 57 uptr mod_offset) { 58 address = addr; 59 module = internal_strdup(mod_name); 60 module_offset = mod_offset; 61 } 62 }; 63 64 struct DataInfo { 65 uptr address; 66 char *module; 67 uptr module_offset; 68 char *name; 69 uptr start; 70 uptr size; 71 }; 72 73 class Symbolizer { 74 public: 75 /// Returns platform-specific implementation of Symbolizer. The symbolizer 76 /// must be initialized (with init or disable) before calling this function. 77 static Symbolizer *Get(); 78 /// Returns platform-specific implementation of Symbolizer, or null if not 79 /// initialized. 80 static Symbolizer *GetOrNull(); 81 /// Returns platform-specific implementation of Symbolizer. Will 82 /// automatically initialize symbolizer as if by calling Init(0) if needed. 83 static Symbolizer *GetOrInit(); 84 /// Initialize and return the symbolizer, given an optional path to an 85 /// external symbolizer. The path argument is only required for legacy 86 /// reasons as this function will check $PATH for an external symbolizer. Not 87 /// thread safe. 88 static Symbolizer *Init(const char* path_to_external = 0); 89 // Fills at most "max_frames" elements of "frames" with descriptions 90 // for a given address (in all inlined functions). Returns the number 91 // of descriptions actually filled. SymbolizePC(uptr address,AddressInfo * frames,uptr max_frames)92 virtual uptr SymbolizePC(uptr address, AddressInfo *frames, uptr max_frames) { 93 return 0; 94 } SymbolizeData(uptr address,DataInfo * info)95 virtual bool SymbolizeData(uptr address, DataInfo *info) { 96 return false; 97 } GetModuleNameAndOffsetForPC(uptr pc,const char ** module_name,uptr * module_address)98 virtual bool GetModuleNameAndOffsetForPC(uptr pc, const char **module_name, 99 uptr *module_address) { 100 return false; 101 } CanReturnFileLineInfo()102 virtual bool CanReturnFileLineInfo() { 103 return false; 104 } 105 // Release internal caches (if any). Flush()106 virtual void Flush() {} 107 // Attempts to demangle the provided C++ mangled name. Demangle(const char * name)108 virtual const char *Demangle(const char *name) { 109 return name; 110 } PrepareForSandboxing()111 virtual void PrepareForSandboxing() {} 112 113 // Allow user to install hooks that would be called before/after Symbolizer 114 // does the actual file/line info fetching. Specific sanitizers may need this 115 // to distinguish system library calls made in user code from calls made 116 // during in-process symbolization. 117 typedef void (*StartSymbolizationHook)(); 118 typedef void (*EndSymbolizationHook)(); 119 // May be called at most once. 120 void AddHooks(StartSymbolizationHook start_hook, 121 EndSymbolizationHook end_hook); 122 123 private: 124 /// Platform-specific function for creating a Symbolizer object. 125 static Symbolizer *PlatformInit(const char *path_to_external); 126 /// Create a symbolizer and store it to symbolizer_ without checking if one 127 /// already exists. Not thread safe. 128 static Symbolizer *CreateAndStore(const char *path_to_external); 129 /// Initialize the symbolizer in a disabled state. Not thread safe. 130 static Symbolizer *Disable(); 131 132 static Symbolizer *symbolizer_; 133 static StaticSpinMutex init_mu_; 134 135 protected: 136 Symbolizer(); 137 138 static LowLevelAllocator symbolizer_allocator_; 139 140 StartSymbolizationHook start_hook_; 141 EndSymbolizationHook end_hook_; 142 class SymbolizerScope { 143 public: 144 explicit SymbolizerScope(const Symbolizer *sym); 145 ~SymbolizerScope(); 146 private: 147 const Symbolizer *sym_; 148 }; 149 }; 150 151 } // namespace __sanitizer 152 153 #endif // SANITIZER_SYMBOLIZER_H 154