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:
parent
d792274003
commit
99b36baa82
4 changed files with 101 additions and 12 deletions
|
@ -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);
|
||||||
|
|
|
@ -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";
|
||||||
|
|
|
@ -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_;
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue