mirror of
https://github.com/yuzu-emu/breakpad.git
synced 2024-11-24 02:25:40 +01:00
Add brief flag to minidump_stackwalk
The added flag will print only one line per frame for the requesting thread (This is mostly the crashing thread). Refactor the code for printing the frame so it can be reused. Bug: 1374075 Change-Id: I8a1c8b1a09740fcaa23c3cc642468622ee64ea73 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/4339771 Reviewed-by: Joshua Peraza <jperaza@chromium.org>
This commit is contained in:
parent
3848d7e3b5
commit
309534f959
@ -61,6 +61,7 @@ struct Options {
|
|||||||
bool machine_readable;
|
bool machine_readable;
|
||||||
bool output_stack_contents;
|
bool output_stack_contents;
|
||||||
bool output_requesting_thread_only;
|
bool output_requesting_thread_only;
|
||||||
|
bool brief;
|
||||||
|
|
||||||
string minidump_file;
|
string minidump_file;
|
||||||
std::vector<string> symbol_paths;
|
std::vector<string> symbol_paths;
|
||||||
@ -114,6 +115,8 @@ bool PrintMinidumpProcess(const Options& options) {
|
|||||||
|
|
||||||
if (options.machine_readable) {
|
if (options.machine_readable) {
|
||||||
PrintProcessStateMachineReadable(process_state);
|
PrintProcessStateMachineReadable(process_state);
|
||||||
|
} else if (options.brief) {
|
||||||
|
PrintRequestingThreadBrief(process_state);
|
||||||
} else {
|
} else {
|
||||||
PrintProcessState(process_state, options.output_stack_contents,
|
PrintProcessState(process_state, options.output_stack_contents,
|
||||||
options.output_requesting_thread_only, &resolver);
|
options.output_requesting_thread_only, &resolver);
|
||||||
@ -135,6 +138,7 @@ static void Usage(int argc, const char *argv[], bool error) {
|
|||||||
" -m Output in machine-readable format\n"
|
" -m Output in machine-readable format\n"
|
||||||
" -s Output stack contents\n"
|
" -s Output stack contents\n"
|
||||||
" -c Output thread that causes crash or dump only\n",
|
" -c Output thread that causes crash or dump only\n",
|
||||||
|
" -b Brief of the thread that causes crash or dump\n",
|
||||||
google_breakpad::BaseName(argv[0]).c_str());
|
google_breakpad::BaseName(argv[0]).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,14 +148,18 @@ static void SetupOptions(int argc, const char *argv[], Options* options) {
|
|||||||
options->machine_readable = false;
|
options->machine_readable = false;
|
||||||
options->output_stack_contents = false;
|
options->output_stack_contents = false;
|
||||||
options->output_requesting_thread_only = false;
|
options->output_requesting_thread_only = false;
|
||||||
|
options->brief = false;
|
||||||
|
|
||||||
while ((ch = getopt(argc, (char * const*)argv, "chms")) != -1) {
|
while ((ch = getopt(argc, (char* const*)argv, "bchms")) != -1) {
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case 'h':
|
case 'h':
|
||||||
Usage(argc, argv, false);
|
Usage(argc, argv, false);
|
||||||
exit(0);
|
exit(0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'b':
|
||||||
|
options->brief = true;
|
||||||
|
break;
|
||||||
case 'c':
|
case 'c':
|
||||||
options->output_requesting_thread_only = true;
|
options->output_requesting_thread_only = true;
|
||||||
break;
|
break;
|
||||||
|
@ -277,6 +277,33 @@ static void PrintStackContents(const string& indent,
|
|||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void PrintFrameHeader(const StackFrame* frame, int frame_index) {
|
||||||
|
printf("%2d ", frame_index);
|
||||||
|
|
||||||
|
uint64_t instruction_address = frame->ReturnAddress();
|
||||||
|
|
||||||
|
if (frame->module) {
|
||||||
|
printf("%s", PathnameStripper::File(frame->module->code_file()).c_str());
|
||||||
|
if (!frame->function_name.empty()) {
|
||||||
|
printf("!%s", frame->function_name.c_str());
|
||||||
|
if (!frame->source_file_name.empty()) {
|
||||||
|
string source_file = PathnameStripper::File(frame->source_file_name);
|
||||||
|
printf(" [%s : %d + 0x%" PRIx64 "]", source_file.c_str(),
|
||||||
|
frame->source_line,
|
||||||
|
instruction_address - frame->source_line_base);
|
||||||
|
} else {
|
||||||
|
printf(" + 0x%" PRIx64, instruction_address - frame->function_base);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
printf(" + 0x%" PRIx64,
|
||||||
|
instruction_address - frame->module->base_address());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
printf("0x%" PRIx64, instruction_address);
|
||||||
|
}
|
||||||
|
printf("\n ");
|
||||||
|
}
|
||||||
|
|
||||||
// PrintStack prints the call stack in |stack| to stdout, in a reasonably
|
// PrintStack prints the call stack in |stack| to stdout, in a reasonably
|
||||||
// useful form. Module, function, and source file names are displayed if
|
// useful form. Module, function, and source file names are displayed if
|
||||||
// they are available. The code offset to the base code address of the
|
// they are available. The code offset to the base code address of the
|
||||||
@ -298,31 +325,7 @@ static void PrintStack(const CallStack* stack,
|
|||||||
}
|
}
|
||||||
for (int frame_index = 0; frame_index < frame_count; ++frame_index) {
|
for (int frame_index = 0; frame_index < frame_count; ++frame_index) {
|
||||||
const StackFrame* frame = stack->frames()->at(frame_index);
|
const StackFrame* frame = stack->frames()->at(frame_index);
|
||||||
printf("%2d ", frame_index);
|
PrintFrameHeader(frame, frame_index);
|
||||||
|
|
||||||
uint64_t instruction_address = frame->ReturnAddress();
|
|
||||||
|
|
||||||
if (frame->module) {
|
|
||||||
printf("%s", PathnameStripper::File(frame->module->code_file()).c_str());
|
|
||||||
if (!frame->function_name.empty()) {
|
|
||||||
printf("!%s", frame->function_name.c_str());
|
|
||||||
if (!frame->source_file_name.empty()) {
|
|
||||||
string source_file = PathnameStripper::File(frame->source_file_name);
|
|
||||||
printf(" [%s : %d + 0x%" PRIx64 "]",
|
|
||||||
source_file.c_str(),
|
|
||||||
frame->source_line,
|
|
||||||
instruction_address - frame->source_line_base);
|
|
||||||
} else {
|
|
||||||
printf(" + 0x%" PRIx64, instruction_address - frame->function_base);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
printf(" + 0x%" PRIx64,
|
|
||||||
instruction_address - frame->module->base_address());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
printf("0x%" PRIx64, instruction_address);
|
|
||||||
}
|
|
||||||
printf("\n ");
|
|
||||||
|
|
||||||
// Inlined frames don't have registers info.
|
// Inlined frames don't have registers info.
|
||||||
if (frame->trust != StackFrameAMD64::FRAME_TRUST_INLINE) {
|
if (frame->trust != StackFrameAMD64::FRAME_TRUST_INLINE) {
|
||||||
@ -1281,4 +1284,20 @@ void PrintProcessStateMachineReadable(const ProcessState& process_state) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PrintRequestingThreadBrief(const ProcessState& process_state) {
|
||||||
|
int requesting_thread = process_state.requesting_thread();
|
||||||
|
if (requesting_thread == -1) {
|
||||||
|
printf(" <no crashing or requesting dump thread identified>\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Thread %d (%s)\n", requesting_thread,
|
||||||
|
process_state.crashed() ? "crashed" : "requested dump, did not crash");
|
||||||
|
const CallStack* stack = process_state.threads()->at(requesting_thread);
|
||||||
|
int frame_count = stack->frames()->size();
|
||||||
|
for (int frame_index = 0; frame_index < frame_count; ++frame_index) {
|
||||||
|
PrintFrameHeader(stack->frames()->at(frame_index), frame_index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace google_breakpad
|
} // namespace google_breakpad
|
||||||
|
@ -43,6 +43,7 @@ void PrintProcessState(const ProcessState& process_state,
|
|||||||
bool output_stack_contents,
|
bool output_stack_contents,
|
||||||
bool output_requesting_thread_only,
|
bool output_requesting_thread_only,
|
||||||
SourceLineResolverInterface* resolver);
|
SourceLineResolverInterface* resolver);
|
||||||
|
void PrintRequestingThreadBrief(const ProcessState& process_state);
|
||||||
|
|
||||||
} // namespace google_breakpad
|
} // namespace google_breakpad
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user