• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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