don't output duplicate filenames in PDBSourceLineWriter. r=mark at http://breakpad.appspot.com/43001

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@431 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
ted.mielczarek 2009-11-23 14:50:55 +00:00
parent 927cc8fa2a
commit 873064894b
2 changed files with 54 additions and 3 deletions

View File

@ -118,11 +118,13 @@ bool PDBSourceLineWriter::PrintLines(IDiaEnumLineNumbers *lines) {
return false;
}
DWORD source_id;
if (FAILED(line->get_sourceFileId(&source_id))) {
DWORD dia_source_id;
if (FAILED(line->get_sourceFileId(&dia_source_id))) {
fprintf(stderr, "failed to get line source file id\n");
return false;
}
// duplicate file names are coalesced to share one ID
DWORD source_id = GetRealFileID(dia_source_id);
DWORD line_num;
if (FAILED(line->get_lineNumber(&line_num))) {
@ -216,7 +218,16 @@ bool PDBSourceLineWriter::PrintSourceFiles() {
return false;
}
fwprintf(output_, L"FILE %d %s\n", file_id, file_name);
wstring file_name_string(file_name);
if (!FileIDIsCached(file_name_string)) {
// this is a new file name, cache it and output a FILE line.
CacheFileID(file_name_string, file_id);
fwprintf(output_, L"FILE %d %s\n", file_id, file_name);
} else {
// this file name has already been seen, just save this
// ID for later lookup.
StoreDuplicateFileID(file_name_string, file_id);
}
file.Release();
}
compiland.Release();

View File

@ -35,6 +35,7 @@
#include <atlcomcli.h>
#include <hash_map>
#include <string>
struct IDiaEnumLineNumbers;
@ -44,6 +45,7 @@ struct IDiaSymbol;
namespace google_breakpad {
using std::wstring;
using stdext::hash_map;
// A structure that carries information that identifies a pdb file.
struct PDBModuleInfo {
@ -137,6 +139,37 @@ class PDBSourceLineWriter {
// its uuid and age.
bool PrintPDBInfo();
// Returns true if this filename has already been seen,
// and an ID is stored for it, or false if it has not.
bool FileIDIsCached(const wstring &file) {
return unique_files_.find(file) != unique_files_.end();
};
// Cache this filename and ID for later reuse.
void CacheFileID(const wstring &file, DWORD id) {
unique_files_[file] = id;
};
// Store this ID in the cache as a duplicate for this filename.
void StoreDuplicateFileID(const wstring &file, DWORD id) {
hash_map<wstring, DWORD>::iterator iter = unique_files_.find(file);
if (iter != unique_files_.end()) {
// map this id to the previously seen one
file_ids_[id] = iter->second;
}
};
// Given a file's unique ID, return the ID that should be used to
// reference it. There may be multiple files with identical filenames
// but different unique IDs. The cache attempts to coalesce these into
// one ID per unique filename.
DWORD GetRealFileID(DWORD id) {
hash_map<DWORD, DWORD>::iterator iter = file_ids_.find(id);
if (iter == file_ids_.end())
return id;
return iter->second;
};
// 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.
@ -156,6 +189,13 @@ class PDBSourceLineWriter {
// The current output file for this WriteMap invocation.
FILE *output_;
// There may be many duplicate filenames with different IDs.
// This maps from the DIA "unique ID" to a single ID per unique
// filename.
hash_map<DWORD, DWORD> file_ids_;
// This maps unique filenames to file IDs.
hash_map<wstring, DWORD> unique_files_;
// Disallow copy ctor and operator=
PDBSourceLineWriter(const PDBSourceLineWriter&);
void operator=(const PDBSourceLineWriter&);