From 80866e79454cefc5570b01dbb0a723185eae653c Mon Sep 17 00:00:00 2001 From: mmentovai Date: Mon, 6 Nov 2006 19:34:19 +0000 Subject: Symbol file should contain module GUID at beginning (#66). r=bryner - The dumped symbol format now begins with a MODULE line identifying the uuid, age, and name of the source pdb file. - The processor ignores MODULE lines, but they are useful in figuring out how to index symbol files in a symbol store. - dump_syms and symupload now both accept either a pdb or exe/dll and will read the pdb regardless. - Figured out that MSSS always represents a module's age in pathnames in hexadecimal, and updated SimpleSymbolSupplier to match. http://groups.google.com/group/airbag-dev/browse_thread/thread/572108d6567edd58 git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@59 4c0a9323-5329-0410-9bdc-e9ce6186880e --- src/common/windows/pdb_source_line_writer.cc | 70 ++++++++++++++++++++++++---- src/common/windows/pdb_source_line_writer.h | 16 +++++-- 2 files changed, 73 insertions(+), 13 deletions(-) (limited to 'src/common/windows') diff --git a/src/common/windows/pdb_source_line_writer.cc b/src/common/windows/pdb_source_line_writer.cc index 5f69775a..58588089 100644 --- a/src/common/windows/pdb_source_line_writer.cc +++ b/src/common/windows/pdb_source_line_writer.cc @@ -77,6 +77,14 @@ bool PDBSourceLineWriter::Open(const wstring &file, FileFormat format) { return false; } break; + case ANY_FILE: + if (FAILED(data_source->loadDataFromPdb(file.c_str()))) { + if (FAILED(data_source->loadDataForExe(file.c_str(), NULL, NULL))) { + fprintf(stderr, "loadDataForPdb and loadDataFromExe failed\n"); + return false; + } + } + break; default: fprintf(stderr, "Unknown file format\n"); return false; @@ -379,6 +387,18 @@ bool PDBSourceLineWriter::PrintCodePublicSymbol(IDiaSymbol *symbol) { return true; } +bool PDBSourceLineWriter::PrintPDBInfo() { + wstring guid, filename; + int age; + if (!GetModuleInfo(&guid, &age, &filename)) { + return false; + } + + fprintf(output_, "MODULE %ws %x %ws\n", guid.c_str(), age, filename.c_str()); + + return true; +} + // wcstol_positive_strict is sort of like wcstol, but much stricter. string // should be a buffer pointing to a null-terminated string containing only // decimal digits. If the entire string can be converted to an integer @@ -608,11 +628,12 @@ next_child: } bool PDBSourceLineWriter::WriteMap(FILE *map_file) { - bool ret = false; output_ = map_file; - if (PrintSourceFiles() && PrintFunctions() && PrintFrameData()) { - ret = true; - } + + bool ret = PrintPDBInfo() && + PrintSourceFiles() && + PrintFunctions() && + PrintFrameData(); output_ = NULL; return ret; @@ -622,18 +643,47 @@ void PDBSourceLineWriter::Close() { session_.Release(); } -wstring PDBSourceLineWriter::GetModuleGUID() { +// static +wstring PDBSourceLineWriter::GetBaseName(const wstring &filename) { + wstring base_name(filename); + size_t slash_pos = base_name.find_last_of(L"/\\"); + if (slash_pos != wstring::npos) { + base_name.erase(0, slash_pos + 1); + } + return base_name; +} + +bool PDBSourceLineWriter::GetModuleInfo(wstring *guid, int *age, + wstring *filename) { + guid->clear(); + *age = 0; + filename->clear(); + CComPtr global; if (FAILED(session_->get_globalScope(&global))) { - return L""; + return false; } - GUID guid; - if (FAILED(global->get_guid(&guid))) { - return L""; + GUID guid_number; + if (FAILED(global->get_guid(&guid_number))) { + return false; } + *guid = GUIDString::GUIDToWString(&guid_number); - return GUIDString::GUIDToWString(&guid); + // DWORD* and int* are not compatible. This is clean and avoids a cast. + DWORD age_dword; + if (FAILED(global->get_age(&age_dword))) { + return false; + } + *age = age_dword; + + CComBSTR filename_string; + if (FAILED(global->get_symbolsFileName(&filename_string))) { + return false; + } + *filename = GetBaseName(wstring(filename_string)); + + return true; } } // namespace google_airbag diff --git a/src/common/windows/pdb_source_line_writer.h b/src/common/windows/pdb_source_line_writer.h index 506a4cb7..5a8fee1d 100644 --- a/src/common/windows/pdb_source_line_writer.h +++ b/src/common/windows/pdb_source_line_writer.h @@ -50,6 +50,7 @@ class PDBSourceLineWriter { enum FileFormat { PDB_FILE, // a .pdb file containing debug symbols EXE_FILE, // a .exe or .dll file + ANY_FILE // try PDB_FILE and then EXE_FILE }; explicit PDBSourceLineWriter(); @@ -73,9 +74,11 @@ class PDBSourceLineWriter { // Closes the current pdb file and its associated resources. void Close(); - // Returns the GUID for the module, as a string, - // e.g. "11111111-2222-3333-4444-555555555555". - wstring GetModuleGUID(); + // Sets guid to the GUID for the module, as a string, + // e.g. "11111111-2222-3333-4444-555555555555". age will be set to the + // age of the pdb file, and filename will be set to the basename of the + // PDB's file name. Returns true on success and false on failure. + bool GetModuleInfo(wstring *guid, int *age, wstring *filename); private: // Outputs the line/address pairs for each line in the enumerator. @@ -102,6 +105,13 @@ class PDBSourceLineWriter { // correspond to code, returns true without outputting anything. bool PrintCodePublicSymbol(IDiaSymbol *symbol); + // Outputs a line identifying the PDB file that is being dumped, along with + // its uuid and age. + bool PrintPDBInfo(); + + // Returns the base name of a file, e.g. strips off the path. + static wstring GetBaseName(const wstring &filename); + // Returns the function name for a symbol. If possible, the name is // undecorated. If the symbol's decorated form indicates the size of // parameters on the stack, this information is returned in stack_param_size. -- cgit v1.2.1