OLD | NEW |
| (Empty) |
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 | |
38 #include <hash_map> | |
39 #include <string> | |
40 | |
41 struct IDiaEnumLineNumbers; | |
42 struct IDiaSession; | |
43 struct IDiaSymbol; | |
44 | |
45 namespace google_breakpad { | |
46 | |
47 using std::wstring; | |
48 using stdext::hash_map; | |
49 | |
50 // A structure that carries information that identifies a pdb file. | |
51 struct PDBModuleInfo { | |
52 public: | |
53 // The basename of the pdb file from which information was loaded. | |
54 wstring debug_file; | |
55 | |
56 // The pdb's identifier. For recent pdb files, the identifier consists | |
57 // of the pdb's guid, in uppercase hexadecimal form without any dashes | |
58 // or separators, followed immediately by the pdb's age, also in | |
59 // uppercase hexadecimal form. For older pdb files which have no guid, | |
60 // the identifier is the pdb's 32-bit signature value, in zero-padded | |
61 // hexadecimal form, followed immediately by the pdb's age, in lowercase | |
62 // hexadecimal form. | |
63 wstring debug_identifier; | |
64 | |
65 // A string identifying the cpu that the pdb is associated with. | |
66 // Currently, this may be "x86" or "unknown". | |
67 wstring cpu; | |
68 }; | |
69 | |
70 class PDBSourceLineWriter { | |
71 public: | |
72 enum FileFormat { | |
73 PDB_FILE, // a .pdb file containing debug symbols | |
74 EXE_FILE, // a .exe or .dll file | |
75 ANY_FILE // try PDB_FILE and then EXE_FILE | |
76 }; | |
77 | |
78 explicit PDBSourceLineWriter(); | |
79 ~PDBSourceLineWriter(); | |
80 | |
81 // Opens the given file. For executable files, the corresponding pdb | |
82 // file must be available; Open will be if it is not. | |
83 // If there is already a pdb file open, it is automatically closed. | |
84 // Returns true on success. | |
85 bool Open(const wstring &file, FileFormat format); | |
86 | |
87 // Locates the pdb file for the given executable (exe or dll) file, | |
88 // and opens it. If there is already a pdb file open, it is automatically | |
89 // closed. Returns true on success. | |
90 bool OpenExecutable(const wstring &exe_file); | |
91 | |
92 // Writes a map file from the current pdb file to the given file stream. | |
93 // Returns true on success. | |
94 bool WriteMap(FILE *map_file); | |
95 | |
96 // Closes the current pdb file and its associated resources. | |
97 void Close(); | |
98 | |
99 // Retrieves information about the module's debugging file. Returns | |
100 // true on success and false on failure. | |
101 bool GetModuleInfo(PDBModuleInfo *info); | |
102 | |
103 // Sets uses_guid to true if the opened file uses a new-style CodeView | |
104 // record with a 128-bit GUID, or false if the opened file uses an old-style | |
105 // CodeView record. When no GUID is available, a 32-bit signature should be | |
106 // used to identify the module instead. If the information cannot be | |
107 // determined, this method returns false. | |
108 bool UsesGUID(bool *uses_guid); | |
109 | |
110 private: | |
111 // Outputs the line/address pairs for each line in the enumerator. | |
112 // Returns true on success. | |
113 bool PrintLines(IDiaEnumLineNumbers *lines); | |
114 | |
115 // Outputs a function address and name, followed by its source line list. | |
116 // block can be the same object as function, or it can be a reference | |
117 // to a code block that is lexically part of this function, but | |
118 // resides at a separate address. | |
119 // Returns true on success. | |
120 bool PrintFunction(IDiaSymbol *function, IDiaSymbol *block); | |
121 | |
122 // Outputs all functions as described above. Returns true on success. | |
123 bool PrintFunctions(); | |
124 | |
125 // Outputs all of the source files in the session's pdb file. | |
126 // Returns true on success. | |
127 bool PrintSourceFiles(); | |
128 | |
129 // Outputs all of the frame information necessary to construct stack | |
130 // backtraces in the absence of frame pointers. Returns true on success. | |
131 bool PrintFrameData(); | |
132 | |
133 // Outputs a single public symbol address and name, if the symbol corresponds | |
134 // to a code address. Returns true on success. If symbol is does not | |
135 // correspond to code, returns true without outputting anything. | |
136 bool PrintCodePublicSymbol(IDiaSymbol *symbol); | |
137 | |
138 // Outputs a line identifying the PDB file that is being dumped, along with | |
139 // its uuid and age. | |
140 bool PrintPDBInfo(); | |
141 | |
142 // Returns true if this filename has already been seen, | |
143 // and an ID is stored for it, or false if it has not. | |
144 bool FileIDIsCached(const wstring &file) { | |
145 return unique_files_.find(file) != unique_files_.end(); | |
146 }; | |
147 | |
148 // Cache this filename and ID for later reuse. | |
149 void CacheFileID(const wstring &file, DWORD id) { | |
150 unique_files_[file] = id; | |
151 }; | |
152 | |
153 // Store this ID in the cache as a duplicate for this filename. | |
154 void StoreDuplicateFileID(const wstring &file, DWORD id) { | |
155 hash_map<wstring, DWORD>::iterator iter = unique_files_.find(file); | |
156 if (iter != unique_files_.end()) { | |
157 // map this id to the previously seen one | |
158 file_ids_[id] = iter->second; | |
159 } | |
160 }; | |
161 | |
162 // Given a file's unique ID, return the ID that should be used to | |
163 // reference it. There may be multiple files with identical filenames | |
164 // but different unique IDs. The cache attempts to coalesce these into | |
165 // one ID per unique filename. | |
166 DWORD GetRealFileID(DWORD id) { | |
167 hash_map<DWORD, DWORD>::iterator iter = file_ids_.find(id); | |
168 if (iter == file_ids_.end()) | |
169 return id; | |
170 return iter->second; | |
171 }; | |
172 | |
173 // Returns the function name for a symbol. If possible, the name is | |
174 // undecorated. If the symbol's decorated form indicates the size of | |
175 // parameters on the stack, this information is returned in stack_param_size. | |
176 // Returns true on success. If the symbol doesn't encode parameter size | |
177 // information, stack_param_size is set to -1. | |
178 static bool GetSymbolFunctionName(IDiaSymbol *function, BSTR *name, | |
179 int *stack_param_size); | |
180 | |
181 // Returns the number of bytes of stack space used for a function's | |
182 // parameters. function must have the tag SymTagFunction. In the event of | |
183 // a failure, returns 0, which is also a valid number of bytes. | |
184 static int GetFunctionStackParamSize(IDiaSymbol *function); | |
185 | |
186 // The session for the currently-open pdb file. | |
187 CComPtr<IDiaSession> session_; | |
188 | |
189 // The current output file for this WriteMap invocation. | |
190 FILE *output_; | |
191 | |
192 // There may be many duplicate filenames with different IDs. | |
193 // This maps from the DIA "unique ID" to a single ID per unique | |
194 // filename. | |
195 hash_map<DWORD, DWORD> file_ids_; | |
196 // This maps unique filenames to file IDs. | |
197 hash_map<wstring, DWORD> unique_files_; | |
198 | |
199 // Disallow copy ctor and operator= | |
200 PDBSourceLineWriter(const PDBSourceLineWriter&); | |
201 void operator=(const PDBSourceLineWriter&); | |
202 }; | |
203 | |
204 } // namespace google_breakpad | |
205 | |
206 #endif // _PDB_SOURCE_LINE_WRITER_H__ | |
OLD | NEW |