From 99b36baa82b7ea8c744e2f66071d27837e897989 Mon Sep 17 00:00:00 2001 From: dmaclach Date: Sat, 15 Sep 2007 00:33:09 +0000 Subject: 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 --- src/tools/mac/crash_report/crash_report.mm | 32 ++++++++--- .../crash_report.xcodeproj/project.pbxproj | 8 ++- .../mac/crash_report/on_demand_symbol_supplier.h | 6 +- .../mac/crash_report/on_demand_symbol_supplier.mm | 67 +++++++++++++++++++++- 4 files changed, 101 insertions(+), 12 deletions(-) (limited to 'src/tools/mac/crash_report') diff --git a/src/tools/mac/crash_report/crash_report.mm b/src/tools/mac/crash_report/crash_report.mm index 9d749349..7171e3f9 100644 --- a/src/tools/mac/crash_report/crash_report.mm +++ b/src/tools/mac/crash_report/crash_report.mm @@ -72,6 +72,7 @@ using google_breakpad::SystemInfo; typedef struct { NSString *minidumpPath; NSString *searchDir; + NSString *symbolSearchDir; } Options; //============================================================================= @@ -190,8 +191,10 @@ static void Start(Options *options) { BasicSourceLineResolver resolver; string search_dir = options->searchDir ? [options->searchDir fileSystemRepresentation] : ""; + string symbol_search_dir = options->symbolSearchDir ? + [options->symbolSearchDir fileSystemRepresentation] : ""; scoped_ptr symbol_supplier( - new OnDemandSymbolSupplier(search_dir)); + new OnDemandSymbolSupplier(search_dir, symbol_search_dir)); scoped_ptr minidump_processor(new MinidumpProcessor(symbol_supplier.get(), &resolver)); ProcessState process_state; @@ -253,12 +256,19 @@ static void Start(Options *options) { //============================================================================= static void Usage(int argc, const char *argv[]) { - fprintf(stderr, "Convert a minidump to a crash report. Breakpad symbol files\n"); - fprintf(stderr, "will be used (or created if missing) in /tmp.\n"); - fprintf(stderr, "Usage: %s [-s search-dir] minidump-file\n", argv[0]); - fprintf(stderr, "\t-s: Specify a search directory to use for missing modules\n"); - fprintf(stderr, "\t-h: Usage\n"); - fprintf(stderr, "\t-?: Usage\n"); + fprintf(stderr, "Convert a minidump to a crash report. Breakpad symbol " + "files will be used (or created if missing) in /tmp.\n" + "If a symbol-file-search-dir is specified, any symbol " + "files in it will be used instead of being loaded from " + "modules on disk.\n" + "If modules cannot be found at the paths stored in the " + "minidump file, they will be searched for at " + "/.\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; 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) { case 's': options->searchDir = [[NSFileManager defaultManager] @@ -274,6 +284,12 @@ static void SetupOptions(int argc, const char *argv[], Options *options) { length:strlen(optarg)]; break; + case 'S': + options->symbolSearchDir = [[NSFileManager defaultManager] + stringWithFileSystemRepresentation:optarg + length:strlen(optarg)]; + break; + case 'h': case '?': Usage(argc, argv); diff --git a/src/tools/mac/crash_report/crash_report.xcodeproj/project.pbxproj b/src/tools/mac/crash_report/crash_report.xcodeproj/project.pbxproj index c52e34f9..9c208227 100644 --- a/src/tools/mac/crash_report/crash_report.xcodeproj/project.pbxproj +++ b/src/tools/mac/crash_report/crash_report.xcodeproj/project.pbxproj @@ -333,6 +333,12 @@ GCC_MODEL_TUNING = G5; GCC_OPTIMIZATION_LEVEL = 0; GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(GCC_PREPROCESSOR_DEFINITIONS)", + _GLIBCXX_DEBUG_PEDANTIC, + _GLIBCXX_DEBUG, + _GLIBCPP_CONCEPT_CHECKS, + ); INSTALL_PATH = "$(HOME)/bin"; OTHER_LDFLAGS = "-lcrypto"; PRODUCT_NAME = crash_report; @@ -350,7 +356,7 @@ ); GCC_C_LANGUAGE_STANDARD = c99; GCC_ENABLE_OBJC_EXCEPTIONS = YES; - GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_MODEL_TUNING = G5; GCC_PRECOMPILE_PREFIX_HEADER = NO; INSTALL_PATH = "$(HOME)/bin"; diff --git a/src/tools/mac/crash_report/on_demand_symbol_supplier.h b/src/tools/mac/crash_report/on_demand_symbol_supplier.h index cedbebb0..0c3ebff9 100644 --- a/src/tools/mac/crash_report/on_demand_symbol_supplier.h +++ b/src/tools/mac/crash_report/on_demand_symbol_supplier.h @@ -47,7 +47,8 @@ class OnDemandSymbolSupplier : public SymbolSupplier { public: // |search_dir| is the directory to search for alternative symbols with // 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() {} // Returns the path to the symbol file for the given module. @@ -58,7 +59,8 @@ class OnDemandSymbolSupplier : public SymbolSupplier { protected: // Search directory string search_dir_; - + string symbol_search_dir_; + // When we create a symbol file for a module, save the name of the module // and the path to that module's symbol file. map module_file_map_; diff --git a/src/tools/mac/crash_report/on_demand_symbol_supplier.mm b/src/tools/mac/crash_report/on_demand_symbol_supplier.mm index 5f3bee91..b8501955 100644 --- a/src/tools/mac/crash_report/on_demand_symbol_supplier.mm +++ b/src/tools/mac/crash_report/on_demand_symbol_supplier.mm @@ -47,8 +47,73 @@ using google_breakpad::PathnameStripper; using google_breakpad::SymbolSupplier; 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) { + 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 -- cgit v1.2.1