sanitizer_symbolizer.h revision 276789
150276Speter//===-- sanitizer_symbolizer.h ----------------------------------*- C++ -*-===//
2166124Srafan//
350276Speter//                     The LLVM Compiler Infrastructure
450276Speter//
550276Speter// This file is distributed under the University of Illinois Open Source
650276Speter// License. See LICENSE.TXT for details.
750276Speter//
850276Speter//===----------------------------------------------------------------------===//
950276Speter//
1050276Speter// Symbolizer is used by sanitizers to map instruction address to a location in
1150276Speter// source code at run-time. Symbolizer either uses __sanitizer_symbolize_*
1250276Speter// defined in the program, or (if they are missing) tries to find and
1350276Speter// launch "llvm-symbolizer" commandline tool in a separate process and
1450276Speter// communicate with it.
1550276Speter//
1650276Speter// Generally we should try to avoid calling system library functions during
1750276Speter// symbolization (and use their replacements from sanitizer_libc.h instead).
1850276Speter//===----------------------------------------------------------------------===//
1950276Speter#ifndef SANITIZER_SYMBOLIZER_H
2050276Speter#define SANITIZER_SYMBOLIZER_H
2150276Speter
2250276Speter#include "sanitizer_common.h"
2350276Speter#include "sanitizer_mutex.h"
2450276Speter
2550276Speternamespace __sanitizer {
2650276Speter
2750276Speterstruct AddressInfo {
2850276Speter  // Owns all the string members. Storage for them is
2950276Speter  // (de)allocated using sanitizer internal allocator.
30166124Srafan  uptr address;
3150276Speter
3250276Speter  char *module;
3350276Speter  uptr module_offset;
3450276Speter
3550276Speter  static const uptr kUnknown = ~(uptr)0;
3650276Speter  char *function;
3750276Speter  uptr function_offset;
3850276Speter
3950276Speter  char *file;
40166124Srafan  int line;
4150276Speter  int column;
4250276Speter
4350276Speter  AddressInfo();
4450276Speter  // Deletes all strings and resets all fields.
4550276Speter  void Clear();
4650276Speter  void FillAddressAndModuleInfo(uptr addr, const char *mod_name,
4750276Speter                                uptr mod_offset);
4850276Speter};
4950276Speter
50166124Srafan// Linked list of symbolized frames (each frame is described by AddressInfo).
5150276Speterstruct SymbolizedStack {
5250276Speter  SymbolizedStack *next;
5350276Speter  AddressInfo info;
5476726Speter  static SymbolizedStack *New(uptr addr);
55166124Srafan  // Deletes current, and all subsequent frames in the linked list.
5650276Speter  // The object cannot be accessed after the call to this function.
57166124Srafan  void ClearAll();
58166124Srafan
59166124Srafan private:
60166124Srafan  SymbolizedStack();
6150276Speter};
6250276Speter
6350276Speter// For now, DataInfo is used to describe global variable.
6450276Speterstruct DataInfo {
6550276Speter  // Owns all the string members. Storage for them is
6650276Speter  // (de)allocated using sanitizer internal allocator.
6750276Speter  char *module;
68166124Srafan  uptr module_offset;
69166124Srafan  char *name;
7050276Speter  uptr start;
7150276Speter  uptr size;
7250276Speter
73166124Srafan  DataInfo();
74166124Srafan  void Clear();
7550276Speter};
7650276Speter
7750276Speterclass Symbolizer {
7850276Speter public:
7950276Speter  /// Initialize and return platform-specific implementation of symbolizer
8050276Speter  /// (if it wasn't already initialized).
8150276Speter  static Symbolizer *GetOrInit();
8250276Speter  // Returns a list of symbolized frames for a given address (containing
8350276Speter  // all inlined functions, if necessary).
8450276Speter  virtual SymbolizedStack *SymbolizePC(uptr address) {
8550276Speter    return SymbolizedStack::New(address);
8650276Speter  }
8750276Speter  virtual bool SymbolizeData(uptr address, DataInfo *info) {
8876726Speter    return false;
89166124Srafan  }
9050276Speter  virtual bool GetModuleNameAndOffsetForPC(uptr pc, const char **module_name,
91166124Srafan                                           uptr *module_address) {
92166124Srafan    return false;
93166124Srafan  }
94166124Srafan  virtual bool CanReturnFileLineInfo() {
9550276Speter    return false;
9650276Speter  }
9750276Speter  // Release internal caches (if any).
98166124Srafan  virtual void Flush() {}
99166124Srafan  // Attempts to demangle the provided C++ mangled name.
100166124Srafan  virtual const char *Demangle(const char *name) {
101166124Srafan    return name;
102166124Srafan  }
103166124Srafan  virtual void PrepareForSandboxing() {}
10450276Speter
10550276Speter  // Allow user to install hooks that would be called before/after Symbolizer
10650276Speter  // does the actual file/line info fetching. Specific sanitizers may need this
10750276Speter  // to distinguish system library calls made in user code from calls made
10850276Speter  // during in-process symbolization.
109  typedef void (*StartSymbolizationHook)();
110  typedef void (*EndSymbolizationHook)();
111  // May be called at most once.
112  void AddHooks(StartSymbolizationHook start_hook,
113                EndSymbolizationHook end_hook);
114
115 private:
116  /// Platform-specific function for creating a Symbolizer object.
117  static Symbolizer *PlatformInit();
118  /// Initialize the symbolizer in a disabled state.  Not thread safe.
119  static Symbolizer *Disable();
120
121  static Symbolizer *symbolizer_;
122  static StaticSpinMutex init_mu_;
123
124 protected:
125  Symbolizer();
126
127  static LowLevelAllocator symbolizer_allocator_;
128
129  StartSymbolizationHook start_hook_;
130  EndSymbolizationHook end_hook_;
131  class SymbolizerScope {
132   public:
133    explicit SymbolizerScope(const Symbolizer *sym);
134    ~SymbolizerScope();
135   private:
136    const Symbolizer *sym_;
137  };
138};
139
140}  // namespace __sanitizer
141
142#endif  // SANITIZER_SYMBOLIZER_H
143