aboutsummaryrefslogtreecommitdiff
path: root/src/processor
diff options
context:
space:
mode:
authorTobias Sargeant <tobiasjs@google.com>2017-10-16 10:22:57 +0100
committerTobias Sargeant <tobiasjs@chromium.org>2017-10-17 10:22:46 +0000
commit3d6076efc24ec6c74cba7729121bf45512a15ba2 (patch)
treee5d34a0da94672ed457674ab33007b75263103e6 /src/processor
parentConvert {mini|micro}dump_stackwalk argument parsing to getopt. (diff)
downloadbreakpad-3d6076efc24ec6c74cba7729121bf45512a15ba2.tar.xz
Add -s flag to microdump_stackwalk for dumping stack contents.
Note that the current MicrodumpProcessor::Process implementation has a bug due to the fact that it creates a local Microdump instance, and then holds onto a pointer to the object returned by microdump.GetMemory() which is destroyed when microdump goes out of scope. This CL fixes the crash by making Microdump outlive MicrodumpProcessor, which is the same pattern that Minidump/MinidumpProcessor uses. Bug: google-breakpad:748 Change-Id: I554b46d309649cf404523722bd9ee39e17a10139 Reviewed-on: https://chromium-review.googlesource.com/720809 Reviewed-by: Primiano Tucci <primiano@chromium.org> Reviewed-by: Ivan Penkov <ivanpe@chromium.org>
Diffstat (limited to 'src/processor')
-rw-r--r--src/processor/microdump.cc1
-rw-r--r--src/processor/microdump_processor.cc22
-rw-r--r--src/processor/microdump_processor_unittest.cc12
-rw-r--r--src/processor/microdump_stackwalk.cc21
4 files changed, 29 insertions, 27 deletions
diff --git a/src/processor/microdump.cc b/src/processor/microdump.cc
index f8922228..2473c35c 100644
--- a/src/processor/microdump.cc
+++ b/src/processor/microdump.cc
@@ -394,4 +394,3 @@ Microdump::Microdump(const string& contents)
}
} // namespace google_breakpad
-
diff --git a/src/processor/microdump_processor.cc b/src/processor/microdump_processor.cc
index c1d8c281..2d3a9558 100644
--- a/src/processor/microdump_processor.cc
+++ b/src/processor/microdump_processor.cc
@@ -54,24 +54,18 @@ MicrodumpProcessor::MicrodumpProcessor(StackFrameSymbolizer* frame_symbolizer)
MicrodumpProcessor::~MicrodumpProcessor() {}
-ProcessResult MicrodumpProcessor::Process(const string &microdump_contents,
+ProcessResult MicrodumpProcessor::Process(Microdump *microdump,
ProcessState* process_state) {
assert(process_state);
process_state->Clear();
- if (microdump_contents.empty()) {
- BPLOG(ERROR) << "Microdump is empty.";
- return PROCESS_ERROR_MINIDUMP_NOT_FOUND;
- }
-
- Microdump microdump(microdump_contents);
- process_state->modules_ = microdump.GetModules()->Copy();
+ process_state->modules_ = microdump->GetModules()->Copy();
scoped_ptr<Stackwalker> stackwalker(
Stackwalker::StackwalkerForCPU(
&process_state->system_info_,
- microdump.GetContext(),
- microdump.GetMemory(),
+ microdump->GetContext(),
+ microdump->GetMemory(),
process_state->modules_,
/* unloaded_modules= */ NULL,
frame_symbolizer_));
@@ -90,12 +84,12 @@ ProcessResult MicrodumpProcessor::Process(const string &microdump_contents,
}
process_state->threads_.push_back(stack.release());
- process_state->thread_memory_regions_.push_back(microdump.GetMemory());
+ process_state->thread_memory_regions_.push_back(microdump->GetMemory());
process_state->crashed_ = true;
process_state->requesting_thread_ = 0;
- process_state->system_info_ = *microdump.GetSystemInfo();
- process_state->crash_reason_ = microdump.GetCrashReason();
- process_state->crash_address_ = microdump.GetCrashAddress();
+ process_state->system_info_ = *microdump->GetSystemInfo();
+ process_state->crash_reason_ = microdump->GetCrashReason();
+ process_state->crash_address_ = microdump->GetCrashAddress();
return PROCESS_OK;
}
diff --git a/src/processor/microdump_processor_unittest.cc b/src/processor/microdump_processor_unittest.cc
index 029259f4..83bdef95 100644
--- a/src/processor/microdump_processor_unittest.cc
+++ b/src/processor/microdump_processor_unittest.cc
@@ -37,6 +37,7 @@
#include "breakpad_googletest_includes.h"
#include "google_breakpad/processor/basic_source_line_resolver.h"
#include "google_breakpad/processor/call_stack.h"
+#include "google_breakpad/processor/microdump.h"
#include "google_breakpad/processor/microdump_processor.h"
#include "google_breakpad/processor/process_state.h"
#include "google_breakpad/processor/stack_frame.h"
@@ -47,6 +48,7 @@
namespace {
using google_breakpad::BasicSourceLineResolver;
+using google_breakpad::Microdump;
using google_breakpad::MicrodumpProcessor;
using google_breakpad::ProcessState;
using google_breakpad::SimpleSymbolSupplier;
@@ -83,7 +85,8 @@ class MicrodumpProcessorTest : public ::testing::Test {
StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
MicrodumpProcessor processor(&frame_symbolizer);
- return processor.Process(microdump_contents, state);
+ Microdump microdump(microdump_contents);
+ return processor.Process(&microdump, state);
}
void AnalyzeDump(const string& microdump_file_name, bool omit_symbols,
@@ -109,13 +112,6 @@ class MicrodumpProcessorTest : public ::testing::Test {
string files_path_;
};
-TEST_F(MicrodumpProcessorTest, TestProcess_Empty) {
- ProcessState state;
- google_breakpad::ProcessResult result =
- ProcessMicrodump("", "", &state);
- ASSERT_EQ(google_breakpad::PROCESS_ERROR_MINIDUMP_NOT_FOUND, result);
-}
-
TEST_F(MicrodumpProcessorTest, TestProcess_Invalid) {
ProcessState state;
google_breakpad::ProcessResult result =
diff --git a/src/processor/microdump_stackwalk.cc b/src/processor/microdump_stackwalk.cc
index 4200636c..46c4127e 100644
--- a/src/processor/microdump_stackwalk.cc
+++ b/src/processor/microdump_stackwalk.cc
@@ -41,6 +41,7 @@
#include "common/scoped_ptr.h"
#include "common/using_std_string.h"
#include "google_breakpad/processor/basic_source_line_resolver.h"
+#include "google_breakpad/processor/microdump.h"
#include "google_breakpad/processor/microdump_processor.h"
#include "google_breakpad/processor/process_state.h"
#include "google_breakpad/processor/stack_frame_symbolizer.h"
@@ -53,12 +54,14 @@ namespace {
struct Options {
bool machine_readable;
+ bool output_stack_contents;
string microdump_file;
std::vector<string> symbol_paths;
};
using google_breakpad::BasicSourceLineResolver;
+using google_breakpad::Microdump;
using google_breakpad::MicrodumpProcessor;
using google_breakpad::ProcessResult;
using google_breakpad::ProcessState;
@@ -81,6 +84,10 @@ int PrintMicrodumpProcess(const Options& options) {
std::vector<char> bytes;
file_stream.seekg(0, std::ios_base::end);
bytes.resize(file_stream.tellg());
+ if (bytes.empty()) {
+ BPLOG(ERROR) << "Microdump is empty.";
+ return 1;
+ }
file_stream.seekg(0, std::ios_base::beg);
file_stream.read(&bytes[0], bytes.size());
string microdump_content(&bytes[0], bytes.size());
@@ -94,14 +101,15 @@ int PrintMicrodumpProcess(const Options& options) {
StackFrameSymbolizer frame_symbolizer(symbol_supplier.get(), &resolver);
ProcessState process_state;
MicrodumpProcessor microdump_processor(&frame_symbolizer);
- ProcessResult res = microdump_processor.Process(microdump_content,
+ Microdump microdump(microdump_content);
+ ProcessResult res = microdump_processor.Process(&microdump,
&process_state);
if (res == google_breakpad::PROCESS_OK) {
if (options.machine_readable) {
PrintProcessStateMachineReadable(process_state);
} else {
- PrintProcessState(process_state, false, &resolver);
+ PrintProcessState(process_state, options.output_stack_contents, &resolver);
}
return 0;
}
@@ -120,7 +128,8 @@ static void Usage(int argc, const char *argv[], bool error) {
"\n"
"Options:\n"
"\n"
- " -m Output in machine-readable format\n",
+ " -m Output in machine-readable format\n"
+ " -s Output stack contents\n",
basename(argv[0]));
}
@@ -128,8 +137,9 @@ static void SetupOptions(int argc, const char *argv[], Options* options) {
int ch;
options->machine_readable = false;
+ options->output_stack_contents = false;
- while ((ch = getopt(argc, (char * const *)argv, "hm")) != -1) {
+ while ((ch = getopt(argc, (char * const *)argv, "hms")) != -1) {
switch (ch) {
case 'h':
Usage(argc, argv, false);
@@ -139,6 +149,9 @@ static void SetupOptions(int argc, const char *argv[], Options* options) {
case 'm':
options->machine_readable = true;
break;
+ case 's':
+ options->output_stack_contents = true;
+ break;
case '?':
Usage(argc, argv, true);