(root)/
gcc-13.2.0/
libsanitizer/
sanitizer_common/
sanitizer_symbolizer_internal.h
       1  //===-- sanitizer_symbolizer_internal.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  // Header for internal classes and functions to be used by implementations of
      10  // symbolizers.
      11  //
      12  //===----------------------------------------------------------------------===//
      13  #ifndef SANITIZER_SYMBOLIZER_INTERNAL_H
      14  #define SANITIZER_SYMBOLIZER_INTERNAL_H
      15  
      16  #include "sanitizer_symbolizer.h"
      17  #include "sanitizer_file.h"
      18  #include "sanitizer_vector.h"
      19  
      20  namespace __sanitizer {
      21  
      22  // Parsing helpers, 'str' is searched for delimiter(s) and a string or uptr
      23  // is extracted. When extracting a string, a newly allocated (using
      24  // InternalAlloc) and null-terminated buffer is returned. They return a pointer
      25  // to the next characted after the found delimiter.
      26  const char *ExtractToken(const char *str, const char *delims, char **result);
      27  const char *ExtractInt(const char *str, const char *delims, int *result);
      28  const char *ExtractUptr(const char *str, const char *delims, uptr *result);
      29  const char *ExtractTokenUpToDelimiter(const char *str, const char *delimiter,
      30                                        char **result);
      31  
      32  const char *DemangleSwiftAndCXX(const char *name);
      33  
      34  // SymbolizerTool is an interface that is implemented by individual "tools"
      35  // that can perform symbolication (external llvm-symbolizer, libbacktrace,
      36  // Windows DbgHelp symbolizer, etc.).
      37  class SymbolizerTool {
      38   public:
      39    // The main |Symbolizer| class implements a "fallback chain" of symbolizer
      40    // tools. In a request to symbolize an address, if one tool returns false,
      41    // the next tool in the chain will be tried.
      42    SymbolizerTool *next;
      43  
      44    SymbolizerTool() : next(nullptr) { }
      45  
      46    // Can't declare pure virtual functions in sanitizer runtimes:
      47    // __cxa_pure_virtual might be unavailable.
      48  
      49    // The |stack| parameter is inout. It is pre-filled with the address,
      50    // module base and module offset values and is to be used to construct
      51    // other stack frames.
      52    virtual bool SymbolizePC(uptr addr, SymbolizedStack *stack) {
      53      UNIMPLEMENTED();
      54    }
      55  
      56    // The |info| parameter is inout. It is pre-filled with the module base
      57    // and module offset values.
      58    virtual bool SymbolizeData(uptr addr, DataInfo *info) {
      59      UNIMPLEMENTED();
      60    }
      61  
      62    virtual bool SymbolizeFrame(uptr addr, FrameInfo *info) {
      63      return false;
      64    }
      65  
      66    virtual void Flush() {}
      67  
      68    // Return nullptr to fallback to the default platform-specific demangler.
      69    virtual const char *Demangle(const char *name) {
      70      return nullptr;
      71    }
      72  
      73   protected:
      74    ~SymbolizerTool() {}
      75  };
      76  
      77  // SymbolizerProcess encapsulates communication between the tool and
      78  // external symbolizer program, running in a different subprocess.
      79  // SymbolizerProcess may not be used from two threads simultaneously.
      80  class SymbolizerProcess {
      81   public:
      82    explicit SymbolizerProcess(const char *path, bool use_posix_spawn = false);
      83    const char *SendCommand(const char *command);
      84  
      85   protected:
      86    ~SymbolizerProcess() {}
      87  
      88    /// The maximum number of arguments required to invoke a tool process.
      89    static const unsigned kArgVMax = 16;
      90  
      91    // Customizable by subclasses.
      92    virtual bool StartSymbolizerSubprocess();
      93    virtual bool ReadFromSymbolizer();
      94    // Return the environment to run the symbolizer in.
      95    virtual char **GetEnvP() { return GetEnviron(); }
      96    InternalMmapVector<char> &GetBuff() { return buffer_; }
      97  
      98   private:
      99    virtual bool ReachedEndOfOutput(const char *buffer, uptr length) const {
     100      UNIMPLEMENTED();
     101    }
     102  
     103    /// Fill in an argv array to invoke the child process.
     104    virtual void GetArgV(const char *path_to_binary,
     105                         const char *(&argv)[kArgVMax]) const {
     106      UNIMPLEMENTED();
     107    }
     108  
     109    bool Restart();
     110    const char *SendCommandImpl(const char *command);
     111    bool WriteToSymbolizer(const char *buffer, uptr length);
     112  
     113    const char *path_;
     114    fd_t input_fd_;
     115    fd_t output_fd_;
     116  
     117    InternalMmapVector<char> buffer_;
     118  
     119    static const uptr kMaxTimesRestarted = 5;
     120    static const int kSymbolizerStartupTimeMillis = 10;
     121    uptr times_restarted_;
     122    bool failed_to_start_;
     123    bool reported_invalid_path_;
     124    bool use_posix_spawn_;
     125  };
     126  
     127  class LLVMSymbolizerProcess;
     128  
     129  // This tool invokes llvm-symbolizer in a subprocess. It should be as portable
     130  // as the llvm-symbolizer tool is.
     131  class LLVMSymbolizer final : public SymbolizerTool {
     132   public:
     133    explicit LLVMSymbolizer(const char *path, LowLevelAllocator *allocator);
     134  
     135    bool SymbolizePC(uptr addr, SymbolizedStack *stack) override;
     136    bool SymbolizeData(uptr addr, DataInfo *info) override;
     137    bool SymbolizeFrame(uptr addr, FrameInfo *info) override;
     138  
     139   private:
     140    const char *FormatAndSendCommand(const char *command_prefix,
     141                                     const char *module_name, uptr module_offset,
     142                                     ModuleArch arch);
     143  
     144    LLVMSymbolizerProcess *symbolizer_process_;
     145    static const uptr kBufferSize = 16 * 1024;
     146    char buffer_[kBufferSize];
     147  };
     148  
     149  // Parses one or more two-line strings in the following format:
     150  //   <function_name>
     151  //   <file_name>:<line_number>[:<column_number>]
     152  // Used by LLVMSymbolizer, Addr2LinePool and InternalSymbolizer, since all of
     153  // them use the same output format.  Returns true if any useful debug
     154  // information was found.
     155  void ParseSymbolizePCOutput(const char *str, SymbolizedStack *res);
     156  
     157  // Parses a two-line string in the following format:
     158  //   <symbol_name>
     159  //   <start_address> <size>
     160  // Used by LLVMSymbolizer and InternalSymbolizer.
     161  void ParseSymbolizeDataOutput(const char *str, DataInfo *info);
     162  
     163  }  // namespace __sanitizer
     164  
     165  #endif  // SANITIZER_SYMBOLIZER_INTERNAL_H