ms_symbol_server_converter.h revision e5dc60822e5938fea2ae892ccddb906641ba174e
1// Copyright (c) 2007, 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// ms_symbol_server_converter.h: Obtain symbol files from a Microsoft 31// symbol server, and convert them to Breakpad's dumped format. 32// 33// At runtime, MSSymbolServerConverter and code that it calls depend on being 34// able to locate suitable versions of dbghelp.dll and symsrv.dll. For best 35// results, place these files in the same directory as the executable. 36// dbghelp.dll and symsrv.dll as supplied with Debugging Tools for Windows are 37// both redistributable, as indicated by the package's redist.txt file. 38// 39// When connecting to Microsoft's symbol server at 40// http://msdl.microsoft.com/download/symbols/, which provides access to 41// symbols for the operating system itself, symsrv.dll requires agreement to 42// Microsoft's "Terms of Use for Microsoft Symbols and Binaries." Because this 43// library places the symbol engine into a promptless mode, the dialog with the 44// terms will not appear, and use of Microsoft's symbol server will not be 45// possible. To indicate agreement to the terms, create a file called 46// symsrv.yes in the same directory as symsrv.dll. (Note that symsrv.dll will 47// also recognize a symsrv.no file as indicating that you do not accept the 48// terms; the .yes file takes priority over the .no file.) The terms of use 49// are contained within symsrv.dll; they were formerly available online at 50// http://www.microsoft.com/whdc/devtools/debugging/symsrvTOU2.mspx , but 51// do not appear to be available online any longer as of January, 2007. It is 52// possible to view the terms from within WinDbg (Debugging Tools for Windows) 53// by removing any symsrv.yes and symsrv.no files from WinDbg's directory, 54// setting the symbol path to include Microsoft's symbol server (.sympath), and 55// attempting to load symbols from their server (.reload). 56// 57// This code has been tested with dbghelp.dll 6.5.3.7 and symsrv.dll 6.5.3.8, 58// included with Microsoft Visual Studio 8 in Common7/IDE. This has also 59// been tested with dbghelp.dll and symsrv.dll 6.6.7.5, included with that 60// version of Debugging Tools for Windows, available at 61// http://www.microsoft.com/whdc/devtools/debugging/ . 62// 63// Author: Mark Mentovai 64 65 66#ifndef MS_SYMBOL_SERVER_CONVERTER_H__ 67#define MS_SYMBOL_SERVER_CONVERTER_H__ 68 69#include <Windows.h> 70 71#include <string> 72#include <vector> 73 74namespace google_breakpad { 75 76using std::string; 77using std::vector; 78 79// MissingSymbolInfo contains the subset of the information in the processor's 80// CodeModule structure relevant to obtaining a missing symbol file. Only 81// debug_file and debug_identifier are relevant in actually obtaining the 82// missing file; the other fields are for convenience. 83struct MissingSymbolInfo { 84 string code_file; 85 string code_identifier; 86 string debug_file; 87 string debug_identifier; 88 string version; 89}; 90 91class GUIDOrSignatureIdentifier { 92 public: 93 enum GUIDOrSignatureType { 94 TYPE_NONE = 0, 95 TYPE_GUID, 96 TYPE_SIGNATURE 97 }; 98 99 GUIDOrSignatureIdentifier() : type_(TYPE_NONE) {} 100 101 // Converts |identifier|, a debug_identifier-formatted string, into its 102 // component fields: either a GUID and age, or signature and age. If 103 // successful, sets the relevant fields in the object, including the type 104 // field, and returns true. On error, returns false. 105 bool InitializeFromString(const string &identifier); 106 107 GUIDOrSignatureType type() const { return type_; } 108 GUID guid() const { return guid_; } 109 DWORD signature() const { return signature_; } 110 int age() const { return age_; } 111 const void *guid_or_signature_pointer() const { return &guid_; } 112 113 private: 114 GUIDOrSignatureType type_; 115 116 // An identifier contains either a 128-bit uuid or a 32-bit signature. 117 union { 118 GUID guid_; 119 DWORD signature_; 120 }; 121 122 // All identifiers used here have age fields, which indicate a specific 123 // revision given a uuid or signature. 124 int age_; 125}; 126 127class MSSymbolServerConverter { 128 public: 129 enum LocateResult { 130 LOCATE_FAILURE = 0, 131 LOCATE_NOT_FOUND, // Authoritative: the file is not present. 132 LOCATE_RETRY, // Transient (network?) error, try again later. 133 LOCATE_SUCCESS 134 }; 135 136 // Create a new object. local_cache is the location (pathname) of a local 137 // symbol store used to hold downloaded and converted symbol files. This 138 // directory will be created by LocateSymbolFile when it successfully 139 // retrieves a symbol file. symbol_servers contains a list of locations (URLs 140 // or pathnames) of the upstream symbol server stores, given in order of 141 // preference, with the first string in the vector identifying the first 142 // store to try. The vector must contain at least one string. None of the 143 // strings passed to this constructor may contain asterisk ('*') or semicolon 144 // (';') characters, as the symbol engine uses these characters as separators. 145 MSSymbolServerConverter(const string &local_cache, 146 const vector<string> &symbol_servers); 147 148 // Locates the symbol file specified by the identifying information in 149 // |missing|, by checking the symbol stores identified when the object 150 // was created. When returning LOCATE_SUCCESS, symbol_file is set to 151 // the pathname of the decompressed symbol file as it is stored in the 152 // local cache. 153 LocateResult LocateSymbolFile(const MissingSymbolInfo &missing, 154 string *symbol_file); 155 156 // Calls LocateSymbolFile and converts the returned symbol file to the 157 // dumped-symbol format, storing it adjacent to the symbol file. The 158 // only conversion supported is from pdb files. Returns the return 159 // value of LocateSymbolFile, or if LocateSymbolFile succeeds but 160 // conversion fails, returns LOCATE_FAILURE. The pathname to the 161 // pdb file and to the converted symbol file are returned in 162 // converted_symbol_file and symbol_file. symbol_file is optional and 163 // may be NULL. If only the converted symbol file is desired, set 164 // keep_symbol_file to false to indicate that the original symbol file 165 // (pdb) should be deleted after conversion. 166 LocateResult LocateAndConvertSymbolFile(const MissingSymbolInfo &missing, 167 bool keep_symbol_file, 168 string *converted_symbol_file, 169 string *symbol_file); 170 171 private: 172 // Called by various SymSrv functions to report status as progress is made 173 // and to allow the callback to influence processing. Messages sent to this 174 // callback can be used to distinguish between the various failure modes 175 // that SymFindFileInPath might encounter. 176 static BOOL CALLBACK SymCallback(HANDLE process, ULONG action, ULONG64 data, 177 ULONG64 context); 178 179 // Called by SymFindFileInPath (in LocateSymbolFile) after a candidate 180 // symbol file is located, when it's present in the local cache. 181 // SymFindFileInPath actually seems to accept NULL for a callback function 182 // and behave properly for our needs in that case, but the documentation 183 // doesn't mention it, so this little callback is provided. 184 static BOOL CALLBACK SymFindFileInPathCallback(char *filename, 185 void *context); 186 187 // The search path used by SymSrv, built based on the arguments to the 188 // constructor. 189 string symbol_path_; 190 191 // SymCallback will set at least one of these failure variables if 192 // SymFindFileInPath fails for an expected reason. 193 bool fail_dns_; // DNS failures (fail_not_found_ will also be set). 194 bool fail_timeout_; // Timeouts (fail_not_found_ will also be set). 195 bool fail_not_found_; // The file could not be found. If this is the only 196 // fail_* member set, then it is authoritative. 197}; 198 199} // namespace google_breakpad 200 201#endif // MS_SYMBOL_SERVER_CONVERTER_H__ 202