diff options
Diffstat (limited to 'src/processor')
-rw-r--r-- | src/processor/crash_report_processor_unittest.cc | 107 | ||||
-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.cc | 118 | ||||
-rw-r--r-- | src/processor/stackwalker.cc | 7 | ||||
-rw-r--r-- | src/processor/stackwalker.h | 9 | ||||
-rw-r--r-- | src/processor/stackwalker_x86.cc | 4 | ||||
-rw-r--r-- | src/processor/stackwalker_x86.h | 2 |
7 files changed, 137 insertions, 126 deletions
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 |