Add stack-dumping logic to crash_report with -t switch

R=jeremy
A=nealsid



git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@357 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
nealsid 2009-07-02 00:30:44 +00:00
parent df55cf4313
commit 6e525cbfbb
3 changed files with 32 additions and 5 deletions

View file

@ -36,8 +36,9 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include "google_breakpad/processor/system_info.h"
#include "google_breakpad/common/breakpad_types.h" #include "google_breakpad/common/breakpad_types.h"
#include "google_breakpad/processor/system_info.h"
#include "google_breakpad/processor/minidump.h"
namespace google_breakpad { namespace google_breakpad {
@ -62,6 +63,9 @@ class ProcessState {
u_int64_t crash_address() const { return crash_address_; } u_int64_t crash_address() const { return crash_address_; }
int requesting_thread() const { return requesting_thread_; } int requesting_thread() const { return requesting_thread_; }
const vector<CallStack*>* threads() const { return &threads_; } const vector<CallStack*>* threads() const { return &threads_; }
const vector<MinidumpMemoryRegion*>* thread_memory_regions() const {
return &thread_memory_regions_;
}
const SystemInfo* system_info() const { return &system_info_; } const SystemInfo* system_info() const { return &system_info_; }
const CodeModules* modules() const { return modules_; } const CodeModules* modules() const { return modules_; }
@ -101,6 +105,7 @@ class ProcessState {
// Stacks for each thread (except possibly the exception handler // Stacks for each thread (except possibly the exception handler
// thread) at the time of the crash. // thread) at the time of the crash.
vector<CallStack*> threads_; vector<CallStack*> threads_;
vector<MinidumpMemoryRegion*> thread_memory_regions_;
// OS and CPU information. // OS and CPU information.
SystemInfo system_info_; SystemInfo system_info_;

View file

@ -206,6 +206,7 @@ ProcessResult MinidumpProcessor::Process(
interrupted = true; interrupted = true;
} }
process_state->threads_.push_back(stack.release()); process_state->threads_.push_back(stack.release());
process_state->thread_memory_regions_.push_back(thread_memory);
} }
if (interrupted) { if (interrupted) {

View file

@ -59,6 +59,7 @@ using google_breakpad::BasicSourceLineResolver;
using google_breakpad::CallStack; using google_breakpad::CallStack;
using google_breakpad::CodeModule; using google_breakpad::CodeModule;
using google_breakpad::CodeModules; using google_breakpad::CodeModules;
using google_breakpad::Minidump;
using google_breakpad::MinidumpProcessor; using google_breakpad::MinidumpProcessor;
using google_breakpad::OnDemandSymbolSupplier; using google_breakpad::OnDemandSymbolSupplier;
using google_breakpad::PathnameStripper; using google_breakpad::PathnameStripper;
@ -73,6 +74,7 @@ typedef struct {
NSString *minidumpPath; NSString *minidumpPath;
NSString *searchDir; NSString *searchDir;
NSString *symbolSearchDir; NSString *symbolSearchDir;
BOOL printThreadMemory;
} Options; } Options;
//============================================================================= //=============================================================================
@ -234,7 +236,13 @@ static void Start(Options *options) {
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;
if (minidump_processor->Process(minidump_file, &process_state) != scoped_ptr<Minidump> dump(new google_breakpad::Minidump(minidump_file));
if (!dump->Read()) {
fprintf(stderr, "Minidump %s could not be read\n", dump->path().c_str());
return;
}
if (minidump_processor->Process(dump.get(), &process_state) !=
google_breakpad::PROCESS_OK) { google_breakpad::PROCESS_OK) {
fprintf(stderr, "MinidumpProcessor::Process failed\n"); fprintf(stderr, "MinidumpProcessor::Process failed\n");
return; return;
@ -274,12 +282,20 @@ static void Start(Options *options) {
// Print all of the threads in the dump. // Print all of the threads in the dump.
int thread_count = process_state.threads()->size(); int thread_count = process_state.threads()->size();
const std::vector<google_breakpad::MinidumpMemoryRegion*>
*thread_memory_regions = process_state.thread_memory_regions();
for (int thread_index = 0; thread_index < thread_count; ++thread_index) { for (int thread_index = 0; thread_index < thread_count; ++thread_index) {
if (thread_index != requesting_thread) { if (thread_index != requesting_thread) {
// Don't print the crash thread again, it was already printed. // Don't print the crash thread again, it was already printed.
printf("\n"); printf("\n");
printf("Thread %d\n", thread_index); printf("Thread %d\n", thread_index);
PrintStack(process_state.threads()->at(thread_index), cpu); PrintStack(process_state.threads()->at(thread_index), cpu);
google_breakpad::MinidumpMemoryRegion *thread_stack_bytes =
thread_memory_regions->at(thread_index);
if (options->printThreadMemory) {
thread_stack_bytes->Print();
}
} }
} }
@ -303,9 +319,11 @@ static void Usage(int argc, const char *argv[]) {
"If modules cannot be found at the paths stored in the " "If modules cannot be found at the paths stored in the "
"minidump file, they will be searched for at " "minidump file, they will be searched for at "
"<module-search-dir>/<path-in-minidump-file>.\n"); "<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, "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" 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-S: Specify a search directory to use for symbol files\n"
"\t-t: Print thread stack memory in hex\n"
"\t-h: Usage\n" "\t-h: Usage\n"
"\t-?: Usage\n"); "\t-?: Usage\n");
} }
@ -315,7 +333,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:s:h?")) != -1) { while ((ch = getopt(argc, (char * const *)argv, "S:s:ht?")) != -1) {
switch (ch) { switch (ch) {
case 's': case 's':
options->searchDir = [[NSFileManager defaultManager] options->searchDir = [[NSFileManager defaultManager]
@ -329,6 +347,9 @@ static void SetupOptions(int argc, const char *argv[], Options *options) {
length:strlen(optarg)]; length:strlen(optarg)];
break; break;
case 't':
options->printThreadMemory = YES;
break;
case 'h': case 'h':
case '?': case '?':
Usage(argc, argv); Usage(argc, argv);