Adds the ability to designate a folder with sym files in it that will be used for symbol matching

to crash_report.


git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@207 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
dmaclach 2007-09-15 00:33:09 +00:00
parent d792274003
commit 99b36baa82
4 changed files with 101 additions and 12 deletions

View file

@ -72,6 +72,7 @@ using google_breakpad::SystemInfo;
typedef struct { typedef struct {
NSString *minidumpPath; NSString *minidumpPath;
NSString *searchDir; NSString *searchDir;
NSString *symbolSearchDir;
} Options; } Options;
//============================================================================= //=============================================================================
@ -190,8 +191,10 @@ static void Start(Options *options) {
BasicSourceLineResolver resolver; BasicSourceLineResolver resolver;
string search_dir = options->searchDir ? string search_dir = options->searchDir ?
[options->searchDir fileSystemRepresentation] : ""; [options->searchDir fileSystemRepresentation] : "";
string symbol_search_dir = options->symbolSearchDir ?
[options->symbolSearchDir fileSystemRepresentation] : "";
scoped_ptr<OnDemandSymbolSupplier> symbol_supplier( scoped_ptr<OnDemandSymbolSupplier> symbol_supplier(
new OnDemandSymbolSupplier(search_dir)); new OnDemandSymbolSupplier(search_dir, symbol_search_dir));
scoped_ptr<MinidumpProcessor> scoped_ptr<MinidumpProcessor>
minidump_processor(new MinidumpProcessor(symbol_supplier.get(), &resolver)); minidump_processor(new MinidumpProcessor(symbol_supplier.get(), &resolver));
ProcessState process_state; ProcessState process_state;
@ -253,12 +256,19 @@ static void Start(Options *options) {
//============================================================================= //=============================================================================
static void Usage(int argc, const char *argv[]) { static void Usage(int argc, const char *argv[]) {
fprintf(stderr, "Convert a minidump to a crash report. Breakpad symbol files\n"); fprintf(stderr, "Convert a minidump to a crash report. Breakpad symbol "
fprintf(stderr, "will be used (or created if missing) in /tmp.\n"); "files will be used (or created if missing) in /tmp.\n"
fprintf(stderr, "Usage: %s [-s search-dir] minidump-file\n", argv[0]); "If a symbol-file-search-dir is specified, any symbol "
fprintf(stderr, "\t-s: Specify a search directory to use for missing modules\n"); "files in it will be used instead of being loaded from "
fprintf(stderr, "\t-h: Usage\n"); "modules on disk.\n"
fprintf(stderr, "\t-?: Usage\n"); "If modules cannot be found at the paths stored in the "
"minidump file, they will be searched for at "
"<module-search-dir>/<path-in-minidump-file>.\n");
fprintf(stderr, "Usage: %s [-s module-search-dir] [-S symbol-file-search-dir] minidump-file\n", argv[0]);
fprintf(stderr, "\t-s: Specify a search directory to use for missing modules\n"
"\t-S: Specify a search directory to use for symbol files\n"
"\t-h: Usage\n"
"\t-?: Usage\n");
} }
//============================================================================= //=============================================================================
@ -266,7 +276,7 @@ static void SetupOptions(int argc, const char *argv[], Options *options) {
extern int optind; extern int optind;
char ch; char ch;
while ((ch = getopt(argc, (char * const *)argv, "s:h?")) != -1) { while ((ch = getopt(argc, (char * const *)argv, "S:s:h?")) != -1) {
switch (ch) { switch (ch) {
case 's': case 's':
options->searchDir = [[NSFileManager defaultManager] options->searchDir = [[NSFileManager defaultManager]
@ -274,6 +284,12 @@ static void SetupOptions(int argc, const char *argv[], Options *options) {
length:strlen(optarg)]; length:strlen(optarg)];
break; break;
case 'S':
options->symbolSearchDir = [[NSFileManager defaultManager]
stringWithFileSystemRepresentation:optarg
length:strlen(optarg)];
break;
case 'h': case 'h':
case '?': case '?':
Usage(argc, argv); Usage(argc, argv);

View file

@ -333,6 +333,12 @@
GCC_MODEL_TUNING = G5; GCC_MODEL_TUNING = G5;
GCC_OPTIMIZATION_LEVEL = 0; GCC_OPTIMIZATION_LEVEL = 0;
GCC_PRECOMPILE_PREFIX_HEADER = NO; GCC_PRECOMPILE_PREFIX_HEADER = NO;
GCC_PREPROCESSOR_DEFINITIONS = (
"$(GCC_PREPROCESSOR_DEFINITIONS)",
_GLIBCXX_DEBUG_PEDANTIC,
_GLIBCXX_DEBUG,
_GLIBCPP_CONCEPT_CHECKS,
);
INSTALL_PATH = "$(HOME)/bin"; INSTALL_PATH = "$(HOME)/bin";
OTHER_LDFLAGS = "-lcrypto"; OTHER_LDFLAGS = "-lcrypto";
PRODUCT_NAME = crash_report; PRODUCT_NAME = crash_report;
@ -350,7 +356,7 @@
); );
GCC_C_LANGUAGE_STANDARD = c99; GCC_C_LANGUAGE_STANDARD = c99;
GCC_ENABLE_OBJC_EXCEPTIONS = YES; GCC_ENABLE_OBJC_EXCEPTIONS = YES;
GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
GCC_MODEL_TUNING = G5; GCC_MODEL_TUNING = G5;
GCC_PRECOMPILE_PREFIX_HEADER = NO; GCC_PRECOMPILE_PREFIX_HEADER = NO;
INSTALL_PATH = "$(HOME)/bin"; INSTALL_PATH = "$(HOME)/bin";

View file

@ -47,7 +47,8 @@ class OnDemandSymbolSupplier : public SymbolSupplier {
public: public:
// |search_dir| is the directory to search for alternative symbols with // |search_dir| is the directory to search for alternative symbols with
// the same name as the module in the minidump // the same name as the module in the minidump
OnDemandSymbolSupplier(const string &search_dir); OnDemandSymbolSupplier(const string &search_dir,
const string &symbol_search_dir);
virtual ~OnDemandSymbolSupplier() {} virtual ~OnDemandSymbolSupplier() {}
// Returns the path to the symbol file for the given module. // Returns the path to the symbol file for the given module.
@ -58,7 +59,8 @@ class OnDemandSymbolSupplier : public SymbolSupplier {
protected: protected:
// Search directory // Search directory
string search_dir_; string search_dir_;
string symbol_search_dir_;
// When we create a symbol file for a module, save the name of the module // When we create a symbol file for a module, save the name of the module
// and the path to that module's symbol file. // and the path to that module's symbol file.
map<string, string> module_file_map_; map<string, string> module_file_map_;

View file

@ -47,8 +47,73 @@ using google_breakpad::PathnameStripper;
using google_breakpad::SymbolSupplier; using google_breakpad::SymbolSupplier;
using google_breakpad::SystemInfo; using google_breakpad::SystemInfo;
OnDemandSymbolSupplier::OnDemandSymbolSupplier(const string &search_dir) OnDemandSymbolSupplier::OnDemandSymbolSupplier(const string &search_dir,
const string &symbol_search_dir)
: search_dir_(search_dir) { : search_dir_(search_dir) {
NSFileManager *mgr = [NSFileManager defaultManager];
int length = symbol_search_dir.length();
if (length) {
// Load all sym files in symbol_search_dir into our module_file_map
// A symbol file always starts with a line like this:
// MODULE mac x86 BBF0A8F9BEADDD2048E6464001CA193F0 GoogleDesktopDaemon
// or
// MODULE mac ppc BBF0A8F9BEADDD2048E6464001CA193F0 GoogleDesktopDaemon
const char *symbolSearchStr = symbol_search_dir.c_str();
NSString *symbolSearchPath =
[mgr stringWithFileSystemRepresentation:symbolSearchStr
length:strlen(symbolSearchStr)];
NSDirectoryEnumerator *dirEnum = [mgr enumeratorAtPath:symbolSearchPath];
NSString *fileName;
NSCharacterSet *hexSet =
[NSCharacterSet characterSetWithCharactersInString:@"0123456789ABCDEF"];
NSCharacterSet *newlineSet =
[NSCharacterSet characterSetWithCharactersInString:@"\r\n"];
while ((fileName = [dirEnum nextObject])) {
// Check to see what type of file we have
NSDictionary *attrib = [dirEnum fileAttributes];
NSString *fileType = [attrib objectForKey:NSFileType];
if ([fileType isEqualToString:NSFileTypeDirectory]) {
// Skip subdirectories
[dirEnum skipDescendents];
} else {
NSString *filePath = [symbolSearchPath stringByAppendingPathComponent:fileName];
NSString *dataStr = [[[NSString alloc] initWithContentsOfFile:filePath] autorelease];
if (dataStr) {
// Check file to see if it is of appropriate type, and grab module
// name.
NSScanner *scanner = [NSScanner scannerWithString:dataStr];
BOOL goodScan = [scanner scanString:@"MODULE mac " intoString:nil];
if (goodScan) {
goodScan = ([scanner scanString:@"x86 " intoString:nil] ||
[scanner scanString:@"ppc " intoString:nil]);
if (goodScan) {
NSString *moduleID;
goodScan = [scanner scanCharactersFromSet:hexSet
intoString:&moduleID];
if (goodScan) {
// Module IDs are always 33 chars long
goodScan = [moduleID length] == 33;
if (goodScan) {
NSString *moduleName;
goodScan = [scanner scanUpToCharactersFromSet:newlineSet
intoString:&moduleName];
if (goodScan) {
goodScan = [moduleName length] > 0;
if (goodScan) {
const char *moduleNameStr = [moduleName UTF8String];
const char *filePathStr = [filePath fileSystemRepresentation];
// Map our file
module_file_map_[moduleNameStr] = filePathStr;
}
}
}
}
}
}
}
}
}
}
} }
SymbolSupplier::SymbolResult SymbolSupplier::SymbolResult