aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZiad Youssef <ziadyoussef@chromium.org>2023-03-15 15:34:30 +0000
committerJoshua Peraza <jperaza@chromium.org>2023-03-15 18:04:57 +0000
commit309534f959c47b1518a1a01817ad7ab4ec20a12b (patch)
tree3860ee37d5049040f0be051167c88fe90d9b8ffc
parent3848d7e3b5365b53452e123c65bcf07a633c58ff (diff)
downloadgoogle-breakpad-309534f959c47b1518a1a01817ad7ab4ec20a12b.tar.gz
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>
-rw-r--r--src/processor/minidump_stackwalk.cc10
-rw-r--r--src/processor/stackwalk_common.cc69
-rw-r--r--src/processor/stackwalk_common.h1
3 files changed, 54 insertions, 26 deletions
diff --git a/src/processor/minidump_stackwalk.cc b/src/processor/minidump_stackwalk.cc
index 5ff61b3c..08c30ed3 100644
--- a/src/processor/minidump_stackwalk.cc
+++ b/src/processor/minidump_stackwalk.cc
@@ -61,6 +61,7 @@ struct Options {
bool machine_readable;
bool output_stack_contents;
bool output_requesting_thread_only;
+ bool brief;
string minidump_file;
std::vector<string> symbol_paths;
@@ -114,6 +115,8 @@ bool PrintMinidumpProcess(const Options& options) {
if (options.machine_readable) {
PrintProcessStateMachineReadable(process_state);
+ } else if (options.brief) {
+ PrintRequestingThreadBrief(process_state);
} else {
PrintProcessState(process_state, options.output_stack_contents,
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"
" -s Output stack contents\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());
}
@@ -144,14 +148,18 @@ static void SetupOptions(int argc, const char *argv[], Options* options) {
options->machine_readable = false;
options->output_stack_contents = 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) {
case 'h':
Usage(argc, argv, false);
exit(0);
break;
+ case 'b':
+ options->brief = true;
+ break;
case 'c':
options->output_requesting_thread_only = true;
break;
diff --git a/src/processor/stackwalk_common.cc b/src/processor/stackwalk_common.cc
index 3a842959..889931ea 100644
--- a/src/processor/stackwalk_common.cc
+++ b/src/processor/stackwalk_common.cc
@@ -277,6 +277,33 @@ static void PrintStackContents(const string& indent,
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
// useful form. Module, function, and source file names are displayed if
// 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) {
const StackFrame* frame = stack->frames()->at(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 ");
+ PrintFrameHeader(frame, frame_index);
// Inlined frames don't have registers info.
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
diff --git a/src/processor/stackwalk_common.h b/src/processor/stackwalk_common.h
index bb12b98f..3782f987 100644
--- a/src/processor/stackwalk_common.h
+++ b/src/processor/stackwalk_common.h
@@ -43,6 +43,7 @@ void PrintProcessState(const ProcessState& process_state,
bool output_stack_contents,
bool output_requesting_thread_only,
SourceLineResolverInterface* resolver);
+void PrintRequestingThreadBrief(const ProcessState& process_state);
} // namespace google_breakpad