aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/google/crash_report.h89
-rw-r--r--src/google/minidump_processor.h (renamed from src/google/crash_report_processor.h)24
-rw-r--r--src/google/symbol_supplier.h5
-rw-r--r--src/processor/crash_report_processor_unittest.cc107
-rw-r--r--src/processor/minidump_processor.cc (renamed from src/processor/crash_report_processor.cc)16
-rw-r--r--src/processor/minidump_processor_unittest.cc118
-rw-r--r--src/processor/stackwalker.cc7
-rw-r--r--src/processor/stackwalker.h9
-rw-r--r--src/processor/stackwalker_x86.cc4
-rw-r--r--src/processor/stackwalker_x86.h2
10 files changed, 152 insertions, 229 deletions
diff --git a/src/google/crash_report.h b/src/google/crash_report.h
deleted file mode 100644
index 22937538..00000000
--- a/src/google/crash_report.h
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright (C) 2006 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// CrashReport encapsulates all of the information for a single report,
-// including data sent with the report and data derived by the minidump
-// processor (stack trace, etc.).
-
-#ifndef GOOGLE_CRASH_REPORT_H__
-#define GOOGLE_CRASH_REPORT_H__
-
-#include <vector>
-#include <string>
-#include "google/airbag_types.h"
-#include "google/stack_frame.h"
-
-namespace google_airbag {
-
-using std::vector;
-using std::string;
-
-struct CrashReport {
- // An optional id for the report. This is supplied by the caller
- // and is not used by airbag.
- string report_id;
-
- // An optional id which identifies the client that generated the report.
- string client_id;
-
- // The time that the report was uploaded (milliseconds since the epoch)
- airbag_time_t report_time;
-
- // The uptime of the process before it crashed
- airbag_time_t process_uptime;
-
- // The cumulative uptime of the application for this user
- airbag_time_t cumulative_product_uptime;
-
- // The user's email address, if they provided it
- string user_email;
-
- // Extra comments the user provided, e.g. steps to reproduce the crash
- string user_comments;
-
- // The product which sent this report
- struct Product {
- string name;
- string version;
- };
- Product product;
-
- // The user's operating system
- struct OS {
- string name;
- string version;
- };
- OS os;
-
- // The user's CPU architecture (x86, PowerPC, x86_64, ...)
- string cpu_arch;
-
- // Extra product-specific key/value pairs
- struct ProductData {
- string key;
- string value;
- };
- vector<ProductData> product_data;
-
- // The stack frames for the crashed thread, top-first.m
- // TODO(bryner): accommodate multiple threads
- StackFrames stack_frames;
-
- // The stack trace "signature", which can be used for matching up reports
- string stack_signature;
-};
-
-} // namespace google_airbag
-
-#endif // GOOGLE_CRASH_REPORT_H__
diff --git a/src/google/crash_report_processor.h b/src/google/minidump_processor.h
index 161bc8cc..9c80ee4e 100644
--- a/src/google/crash_report_processor.h
+++ b/src/google/minidump_processor.h
@@ -12,28 +12,30 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#ifndef GOOGLE_CRASH_REPORT_PROCESSOR_H__
-#define GOOGLE_CRASH_REPORT_PROCESSOR_H__
+#ifndef GOOGLE_MINIDUMP_PROCESSOR_H__
+#define GOOGLE_MINIDUMP_PROCESSOR_H__
#include <string>
+#include "google/stack_frame.h"
namespace google_airbag {
using std::string;
-struct CrashReport;
class SymbolSupplier;
-class CrashReportProcessor {
+class MinidumpProcessor {
public:
- // Initializes this CrashReportProcessor. supplier should be an
+ // Initializes this MinidumpProcessor. supplier should be an
// implementation of the SymbolSupplier abstract base class.
- CrashReportProcessor(SymbolSupplier *supplier);
- ~CrashReportProcessor();
+ MinidumpProcessor(SymbolSupplier *supplier);
+ ~MinidumpProcessor();
- // Fills in the stack and other derived data for the CrashReport,
- // using the supplied minidump file. Returns true on success.
- bool ProcessReport(CrashReport *report, const string &minidump_file);
+ // Fills in the given StackFrames vector by processing the minidump file.
+ // supplier_data is an opaque pointer which is passed to
+ // SymbolSupplier::GetSymbolFile(). Returns true on success.
+ bool Process(const string &minidump_file, void *supplier_data,
+ StackFrames *stack_frames);
private:
SymbolSupplier *supplier_;
@@ -41,4 +43,4 @@ class CrashReportProcessor {
} // namespace google_airbag
-#endif // GOOGLE_CRASH_REPORT_PROCESSOR_H__
+#endif // GOOGLE_MINIDUMP_PROCESSOR_H__
diff --git a/src/google/symbol_supplier.h b/src/google/symbol_supplier.h
index 279e99f2..f0a6e39c 100644
--- a/src/google/symbol_supplier.h
+++ b/src/google/symbol_supplier.h
@@ -24,16 +24,15 @@ namespace google_airbag {
using std::string;
class MinidumpModule;
-struct CrashReport;
class SymbolSupplier {
public:
virtual ~SymbolSupplier() {}
// Returns the path to the symbol file for the given module.
- // report will be the pointer supplied to ProcessReport().
+ // supplier_data is passed through from MinidumpProcessor::Process().
virtual string GetSymbolFile(MinidumpModule *module,
- const CrashReport *report) = 0;
+ void *supplier_data) = 0;
};
} // namespace google_airbag
diff --git a/src/processor/crash_report_processor_unittest.cc b/src/processor/crash_report_processor_unittest.cc
deleted file mode 100644
index 66694a21..00000000
--- a/src/processor/crash_report_processor_unittest.cc
+++ /dev/null
@@ -1,107 +0,0 @@
-// Copyright (C) 2006 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Unit test for CrashReporter. Uses a pre-generated minidump and
-// corresponding symbol file, and checks the contents of the CrashReport.
-
-#include <string>
-#include "google/crash_report.h"
-#include "google/crash_report_processor.h"
-#include "google/symbol_supplier.h"
-#include "processor/minidump.h"
-
-using std::string;
-using google_airbag::CrashReportProcessor;
-using google_airbag::CrashReport;
-
-#define ASSERT_TRUE(cond) \
- if (!(cond)) { \
- fprintf(stderr, "FAILED: %s at %s:%d\n", #cond, __FILE__, __LINE__); \
- return false; \
- }
-
-#define ASSERT_EQ(e1, e2) ASSERT_TRUE((e1) == (e2))
-
-namespace google_airbag {
-
-class TestSymbolSupplier : public SymbolSupplier {
- public:
- virtual string GetSymbolFile(MinidumpModule *module,
- const CrashReport *report);
-};
-
-string TestSymbolSupplier::GetSymbolFile(MinidumpModule *module,
- const CrashReport *report) {
- if (*(module->GetName()) == "c:\\test_app.exe") {
- return string(getenv("srcdir") ? getenv("srcdir") : ".") +
- "/src/processor/testdata/minidump2.sym";
- }
-
- return "";
-}
-
-} // namespace google_airbag
-
-using google_airbag::TestSymbolSupplier;
-
-static bool RunTests() {
-
- TestSymbolSupplier supplier;
- CrashReportProcessor processor(&supplier);
-
- CrashReport report;
- string minidump_file = string(getenv("srcdir") ? getenv("srcdir") : ".") +
- "/src/processor/testdata/minidump2.dmp";
-
- ASSERT_TRUE(processor.ProcessReport(&report, minidump_file));
- ASSERT_EQ(report.stack_frames.size(), 4);
-
- ASSERT_EQ(report.stack_frames[0].module_base, 0x400000);
- ASSERT_EQ(report.stack_frames[0].module_name, "c:\\test_app.exe");
- ASSERT_EQ(report.stack_frames[0].function_name, "CrashFunction");
- ASSERT_EQ(report.stack_frames[0].source_file_name, "c:\\test_app.cc");
- ASSERT_EQ(report.stack_frames[0].source_line, 36);
-
- ASSERT_EQ(report.stack_frames[1].module_base, 0x400000);
- ASSERT_EQ(report.stack_frames[1].module_name, "c:\\test_app.exe");
- ASSERT_EQ(report.stack_frames[1].function_name, "main");
- ASSERT_EQ(report.stack_frames[1].source_file_name, "c:\\test_app.cc");
- ASSERT_EQ(report.stack_frames[1].source_line, 42);
-
- // This comes from the CRT
- ASSERT_EQ(report.stack_frames[2].module_base, 0x400000);
- ASSERT_EQ(report.stack_frames[2].module_name, "c:\\test_app.exe");
- ASSERT_EQ(report.stack_frames[2].function_name, "__tmainCRTStartup");
- ASSERT_EQ(report.stack_frames[2].source_file_name,
- "f:\\rtm\\vctools\\crt_bld\\self_x86\\crt\\src\\crt0.c");
- ASSERT_EQ(report.stack_frames[2].source_line, 318);
-
- // No debug info available for kernel32.dll
- ASSERT_EQ(report.stack_frames[3].module_base, 0x7c800000);
- ASSERT_EQ(report.stack_frames[3].module_name,
- "C:\\WINDOWS\\system32\\kernel32.dll");
- ASSERT_TRUE(report.stack_frames[3].function_name.empty());
- ASSERT_TRUE(report.stack_frames[3].source_file_name.empty());
- ASSERT_EQ(report.stack_frames[3].source_line, 0);
-
- return true;
-}
-
-int main(int argc, char *argv[]) {
- if (!RunTests()) {
- return 1;
- }
-
- return 0;
-}
diff --git a/src/processor/crash_report_processor.cc b/src/processor/minidump_processor.cc
index 672ca7f0..74e478a6 100644
--- a/src/processor/crash_report_processor.cc
+++ b/src/processor/minidump_processor.cc
@@ -12,22 +12,22 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#include "google/crash_report.h"
-#include "google/crash_report_processor.h"
+#include "google/minidump_processor.h"
#include "processor/minidump.h"
#include "processor/stackwalker_x86.h"
namespace google_airbag {
-CrashReportProcessor::CrashReportProcessor(SymbolSupplier *supplier)
+MinidumpProcessor::MinidumpProcessor(SymbolSupplier *supplier)
: supplier_(supplier) {
}
-CrashReportProcessor::~CrashReportProcessor() {
+MinidumpProcessor::~MinidumpProcessor() {
}
-bool CrashReportProcessor::ProcessReport(CrashReport *report,
- const string &minidump_file) {
+bool MinidumpProcessor::Process(const string &minidump_file,
+ void *supplier_data,
+ StackFrames *stack_frames) {
Minidump dump(minidump_file);
if (!dump.Read()) {
return false;
@@ -56,8 +56,8 @@ bool CrashReportProcessor::ProcessReport(CrashReport *report,
// TODO(bryner): figure out which StackWalker we want
StackwalkerX86 walker(exception->GetContext(), thread_memory,
- dump.GetModuleList(), supplier_, report);
- walker.Walk(&report->stack_frames);
+ dump.GetModuleList(), supplier_, supplier_data);
+ walker.Walk(stack_frames);
return true;
}
diff --git a/src/processor/minidump_processor_unittest.cc b/src/processor/minidump_processor_unittest.cc
new file mode 100644
index 00000000..b73469b5
--- /dev/null
+++ b/src/processor/minidump_processor_unittest.cc
@@ -0,0 +1,118 @@
+// Copyright (C) 2006 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Unit test for MinidumpProcessor. Uses a pre-generated minidump and
+// corresponding symbol file, and checks the stack frames for correctness.
+
+#include <string>
+#include "google/minidump_processor.h"
+#include "google/symbol_supplier.h"
+#include "processor/minidump.h"
+
+using std::string;
+using google_airbag::MinidumpProcessor;
+using google_airbag::StackFrames;
+
+#define ASSERT_TRUE(cond) \
+ if (!(cond)) { \
+ fprintf(stderr, "FAILED: %s at %s:%d\n", #cond, __FILE__, __LINE__); \
+ return false; \
+ }
+
+#define ASSERT_EQ(e1, e2) ASSERT_TRUE((e1) == (e2))
+
+namespace google_airbag {
+
+class TestSymbolSupplier : public SymbolSupplier {
+ public:
+ TestSymbolSupplier() : has_supplier_data_(false) {}
+ virtual ~TestSymbolSupplier() {}
+
+ virtual string GetSymbolFile(MinidumpModule *module, void *supplier_data);
+
+ // This member is used to test the data argument to GetSymbolFile.
+ // If the argument is correct, it's set to true.
+ bool has_supplier_data_;
+};
+
+string TestSymbolSupplier::GetSymbolFile(MinidumpModule *module,
+ void *supplier_data) {
+ if (supplier_data == &has_supplier_data_) {
+ has_supplier_data_ = true;
+ }
+
+ if (*(module->GetName()) == "c:\\test_app.exe") {
+ return string(getenv("srcdir") ? getenv("srcdir") : ".") +
+ "/src/processor/testdata/minidump2.sym";
+ }
+
+ return "";
+}
+
+} // namespace google_airbag
+
+using google_airbag::TestSymbolSupplier;
+
+static bool RunTests() {
+
+ TestSymbolSupplier supplier;
+ MinidumpProcessor processor(&supplier);
+
+ StackFrames stack_frames;
+ string minidump_file = string(getenv("srcdir") ? getenv("srcdir") : ".") +
+ "/src/processor/testdata/minidump2.dmp";
+
+ ASSERT_TRUE(processor.Process(minidump_file,
+ &supplier.has_supplier_data_, &stack_frames));
+ ASSERT_TRUE(supplier.has_supplier_data_);
+ ASSERT_EQ(stack_frames.size(), 4);
+
+ ASSERT_EQ(stack_frames[0].module_base, 0x400000);
+ ASSERT_EQ(stack_frames[0].module_name, "c:\\test_app.exe");
+ ASSERT_EQ(stack_frames[0].function_name, "CrashFunction");
+ ASSERT_EQ(stack_frames[0].source_file_name, "c:\\test_app.cc");
+ ASSERT_EQ(stack_frames[0].source_line, 36);
+
+ ASSERT_EQ(stack_frames[1].module_base, 0x400000);
+ ASSERT_EQ(stack_frames[1].module_name, "c:\\test_app.exe");
+ ASSERT_EQ(stack_frames[1].function_name, "main");
+ ASSERT_EQ(stack_frames[1].source_file_name, "c:\\test_app.cc");
+ ASSERT_EQ(stack_frames[1].source_line, 42);
+
+ // This comes from the CRT
+ ASSERT_EQ(stack_frames[2].module_base, 0x400000);
+ ASSERT_EQ(stack_frames[2].module_name, "c:\\test_app.exe");
+ ASSERT_EQ(stack_frames[2].function_name, "__tmainCRTStartup");
+ ASSERT_EQ(stack_frames[2].source_file_name,
+ "f:\\rtm\\vctools\\crt_bld\\self_x86\\crt\\src\\crt0.c");
+ ASSERT_EQ(stack_frames[2].source_line, 318);
+
+ // No debug info available for kernel32.dll
+ ASSERT_EQ(stack_frames[3].module_base, 0x7c800000);
+ ASSERT_EQ(stack_frames[3].module_name,
+ "C:\\WINDOWS\\system32\\kernel32.dll");
+ ASSERT_TRUE(stack_frames[3].function_name.empty());
+ ASSERT_TRUE(stack_frames[3].source_file_name.empty());
+ ASSERT_EQ(stack_frames[3].source_line, 0);
+
+ return true;
+}
+
+int main(int argc, char *argv[]) {
+ if (!RunTests()) {
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/src/processor/stackwalker.cc b/src/processor/stackwalker.cc
index 0103e850..62386b83 100644
--- a/src/processor/stackwalker.cc
+++ b/src/processor/stackwalker.cc
@@ -34,11 +34,11 @@ using std::auto_ptr;
Stackwalker::Stackwalker(MemoryRegion* memory, MinidumpModuleList* modules,
- SymbolSupplier *supplier, const CrashReport *report)
+ SymbolSupplier* supplier, void* supplier_data)
: memory_(memory),
modules_(modules),
supplier_(supplier),
- report_(report) {
+ supplier_data_(supplier_data) {
}
@@ -64,7 +64,8 @@ void Stackwalker::Walk(StackFrames *frames) {
frame->module_name = *(module->GetName());
frame->module_base = module->base_address();
if (modules_ && supplier_) {
- string symbol_file = supplier_->GetSymbolFile(module, report_);
+ string symbol_file =
+ supplier_->GetSymbolFile(module, supplier_data_);
if (!symbol_file.empty()) {
resolver.LoadModule(*(module->GetName()), symbol_file);
resolver.FillSourceLineInfo(frame.get());
diff --git a/src/processor/stackwalker.h b/src/processor/stackwalker.h
index 07a78ca2..bfcb783a 100644
--- a/src/processor/stackwalker.h
+++ b/src/processor/stackwalker.h
@@ -37,7 +37,6 @@ namespace google_airbag {
class MinidumpModuleList;
class SymbolSupplier;
-struct CrashReport;
class Stackwalker {
@@ -55,12 +54,12 @@ class Stackwalker {
// that is used to look up which code module each stack frame is
// associated with. supplier is an optional caller-supplied SymbolSupplier
// implementation. If supplier is NULL, source line info will not be
- // resolved. The CrashReport object will be passed to the SymbolSupplier's
+ // resolved. supplier_data will be passed to the SymbolSupplier's
// GetSymbolFile method.
Stackwalker(MemoryRegion* memory,
MinidumpModuleList* modules,
SymbolSupplier* supplier,
- const CrashReport* report);
+ void* supplier_data);
// The stack memory to walk. Subclasses will require this region to
// get information from the stack.
@@ -85,8 +84,8 @@ class Stackwalker {
// The optional SymbolSupplier for resolving source line info.
SymbolSupplier* supplier_;
- // The CrashReport object which is passed to the SymbolSupplier. May be null.
- const CrashReport* report_;
+ // Caller-supplied data to be passed to the symbol supplier
+ void* supplier_data_;
};
diff --git a/src/processor/stackwalker_x86.cc b/src/processor/stackwalker_x86.cc
index b7adfaf9..654cb17e 100644
--- a/src/processor/stackwalker_x86.cc
+++ b/src/processor/stackwalker_x86.cc
@@ -30,8 +30,8 @@ StackwalkerX86::StackwalkerX86(MinidumpContext* context,
MemoryRegion* memory,
MinidumpModuleList* modules,
SymbolSupplier* supplier,
- const CrashReport* report)
- : Stackwalker(memory, modules, supplier, report),
+ void* supplier_data)
+ : Stackwalker(memory, modules, supplier, supplier_data),
last_frame_pointer_(0) {
if (memory_->GetBase() + memory_->GetSize() - 1 > 0xffffffff) {
// The x86 is a 32-bit CPU, the limits of the supplied stack are invalid.
diff --git a/src/processor/stackwalker_x86.h b/src/processor/stackwalker_x86.h
index 8f175004..34be57eb 100644
--- a/src/processor/stackwalker_x86.h
+++ b/src/processor/stackwalker_x86.h
@@ -46,7 +46,7 @@ class StackwalkerX86 : public Stackwalker {
MemoryRegion* memory,
MinidumpModuleList* modules,
SymbolSupplier* supplier,
- const CrashReport* report);
+ void* supplier_data);
private:
// Implementation of Stackwalker, using x86 context (%ebp, %eip) and