1 // Copyright (c) 2006, Google Inc. 2 // All rights reserved. 3 // 4 // Redistribution and use in source and binary forms, with or without 5 // modification, are permitted provided that the following conditions are 6 // met: 7 // 8 // * Redistributions of source code must retain the above copyright 9 // notice, this list of conditions and the following disclaimer. 10 // * Redistributions in binary form must reproduce the above 11 // copyright notice, this list of conditions and the following disclaimer 12 // in the documentation and/or other materials provided with the 13 // distribution. 14 // * Neither the name of Google Inc. nor the names of its 15 // contributors may be used to endorse or promote products derived from 16 // this software without specific prior written permission. 17 // 18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 30 // PDBSourceLineWriter uses a pdb file produced by Visual C++ to output 31 // a line/address map for use with BasicSourceLineResolver. 32 33 #ifndef _PDB_SOURCE_LINE_WRITER_H__ 34 #define _PDB_SOURCE_LINE_WRITER_H__ 35 36 #include <atlcomcli.h> 37 #ifdef MSVC_EXPRESS_FIX // HINT: this is defined by a fake atlcomcli.h which is used if the system one is not found 38 #include <atlbase.h> 39 using ATL::CComPtr; 40 #endif 41 42 #include <string> 43 44 struct IDiaEnumLineNumbers; 45 struct IDiaSession; 46 struct IDiaSymbol; 47 48 namespace google_breakpad { 49 50 using std::wstring; 51 52 // A structure that carries information that identifies a pdb file. 53 struct PDBModuleInfo { 54 public: 55 // The basename of the pdb file from which information was loaded. 56 wstring debug_file; 57 58 // The pdb's identifier. For recent pdb files, the identifier consists 59 // of the pdb's guid, in uppercase hexadecimal form without any dashes 60 // or separators, followed immediately by the pdb's age, also in 61 // uppercase hexadecimal form. For older pdb files which have no guid, 62 // the identifier is the pdb's 32-bit signature value, in zero-padded 63 // hexadecimal form, followed immediately by the pdb's age, in lowercase 64 // hexadecimal form. 65 wstring debug_identifier; 66 67 // A string identifying the cpu that the pdb is associated with. 68 // Currently, this may be "x86" or "unknown". 69 wstring cpu; 70 }; 71 72 class PDBSourceLineWriter { 73 public: 74 enum FileFormat { 75 PDB_FILE, // a .pdb file containing debug symbols 76 EXE_FILE, // a .exe or .dll file 77 ANY_FILE // try PDB_FILE and then EXE_FILE 78 }; 79 80 explicit PDBSourceLineWriter(); 81 ~PDBSourceLineWriter(); 82 83 // Opens the given file. For executable files, the corresponding pdb 84 // file must be available; Open will be if it is not. 85 // If there is already a pdb file open, it is automatically closed. 86 // Returns true on success. 87 bool Open(const wstring &file, FileFormat format); 88 89 // Locates the pdb file for the given executable (exe or dll) file, 90 // and opens it. If there is already a pdb file open, it is automatically 91 // closed. Returns true on success. 92 bool OpenExecutable(const wstring &exe_file); 93 94 // Writes a map file from the current pdb file to the given file stream. 95 // Returns true on success. 96 bool WriteMap(FILE *map_file); 97 98 // Closes the current pdb file and its associated resources. 99 void Close(); 100 101 // Retrieves information about the module's debugging file. Returns 102 // true on success and false on failure. 103 bool GetModuleInfo(PDBModuleInfo *info); 104 105 // Sets uses_guid to true if the opened file uses a new-style CodeView 106 // record with a 128-bit GUID, or false if the opened file uses an old-style 107 // CodeView record. When no GUID is available, a 32-bit signature should be 108 // used to identify the module instead. If the information cannot be 109 // determined, this method returns false. 110 bool UsesGUID(bool *uses_guid); 111 112 private: 113 // Outputs the line/address pairs for each line in the enumerator. 114 // Returns true on success. 115 bool PrintLines(IDiaEnumLineNumbers *lines); 116 117 // Outputs a function address and name, followed by its source line list. 118 // Returns true on success. 119 bool PrintFunction(IDiaSymbol *function); 120 121 // Outputs all functions as described above. Returns true on success. 122 bool PrintFunctions(); 123 124 // Outputs all of the source files in the session's pdb file. 125 // Returns true on success. 126 bool PrintSourceFiles(); 127 128 // Outputs all of the frame information necessary to construct stack 129 // backtraces in the absence of frame pointers. Returns true on success. 130 bool PrintFrameData(); 131 132 // Outputs a single public symbol address and name, if the symbol corresponds 133 // to a code address. Returns true on success. If symbol is does not 134 // correspond to code, returns true without outputting anything. 135 bool PrintCodePublicSymbol(IDiaSymbol *symbol); 136 137 // Outputs a line identifying the PDB file that is being dumped, along with 138 // its uuid and age. 139 bool PrintPDBInfo(); 140 141 // Returns the function name for a symbol. If possible, the name is 142 // undecorated. If the symbol's decorated form indicates the size of 143 // parameters on the stack, this information is returned in stack_param_size. 144 // Returns true on success. If the symbol doesn't encode parameter size 145 // information, stack_param_size is set to -1. 146 static bool GetSymbolFunctionName(IDiaSymbol *function, BSTR *name, 147 int *stack_param_size); 148 149 // Returns the number of bytes of stack space used for a function's 150 // parameters. function must have the tag SymTagFunction. In the event of 151 // a failure, returns 0, which is also a valid number of bytes. 152 static int GetFunctionStackParamSize(IDiaSymbol *function); 153 154 // The session for the currently-open pdb file. 155 CComPtr<IDiaSession> session_; 156 157 // The current output file for this WriteMap invocation. 158 FILE *output_; 159 160 // Disallow copy ctor and operator= 161 PDBSourceLineWriter(const PDBSourceLineWriter&); 162 void operator=(const PDBSourceLineWriter&); 163 }; 164 165 } // namespace google_breakpad 166 167 #endif // _PDB_SOURCE_LINE_WRITER_H__ 168