mirror of
https://github.com/yuzu-emu/breakpad.git
synced 2025-04-18 04:51:43 +00:00
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:
parent
df55cf4313
commit
6e525cbfbb
|
@ -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_;
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue