diff options
Diffstat (limited to 'externals/breakpad/src/processor/microdump_processor_unittest.cc')
-rw-r--r-- | externals/breakpad/src/processor/microdump_processor_unittest.cc | 288 |
1 files changed, 288 insertions, 0 deletions
diff --git a/externals/breakpad/src/processor/microdump_processor_unittest.cc b/externals/breakpad/src/processor/microdump_processor_unittest.cc new file mode 100644 index 0000000000..47f5e35ec2 --- /dev/null +++ b/externals/breakpad/src/processor/microdump_processor_unittest.cc @@ -0,0 +1,288 @@ +// Copyright 2014 Google LLC +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google LLC nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Unit test for MicrodumpProcessor. + +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + +#include <fstream> +#include <iostream> +#include <string> +#include <vector> + +#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" +#include "google_breakpad/processor/stack_frame_symbolizer.h" +#include "processor/simple_symbol_supplier.h" +#include "processor/stackwalker_unittest_utils.h" + +namespace { + +using google_breakpad::BasicSourceLineResolver; +using google_breakpad::Microdump; +using google_breakpad::MicrodumpProcessor; +using google_breakpad::ProcessState; +using google_breakpad::SimpleSymbolSupplier; +using google_breakpad::StackFrameSymbolizer; + +class MicrodumpProcessorTest : public ::testing::Test { + public: + MicrodumpProcessorTest() + : files_path_(string(getenv("srcdir") ? getenv("srcdir") : ".") + + "/src/processor/testdata/") { + } + + void ReadFile(const string& file_name, string* file_contents) { + assert(file_contents); + std::ifstream file_stream(file_name.c_str(), std::ios::in); + ASSERT_TRUE(file_stream.good()); + std::vector<char> bytes; + file_stream.seekg(0, std::ios_base::end); + ASSERT_TRUE(file_stream.good()); + bytes.resize(file_stream.tellg()); + file_stream.seekg(0, std::ios_base::beg); + ASSERT_TRUE(file_stream.good()); + file_stream.read(&bytes[0], bytes.size()); + ASSERT_TRUE(file_stream.good()); + *file_contents = string(&bytes[0], bytes.size()); + } + + google_breakpad::ProcessResult ProcessMicrodump( + const string& symbols_file, + const string& microdump_contents, + ProcessState* state) { + SimpleSymbolSupplier supplier(symbols_file); + BasicSourceLineResolver resolver; + StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); + MicrodumpProcessor processor(&frame_symbolizer); + + Microdump microdump(microdump_contents); + return processor.Process(µdump, state); + } + + void AnalyzeDump(const string& microdump_file_name, bool omit_symbols, + int expected_cpu_count, ProcessState* state) { + string symbols_file = omit_symbols ? "" : files_path_ + "symbols/microdump"; + string microdump_file_path = files_path_ + microdump_file_name; + string microdump_contents; + ReadFile(microdump_file_path, µdump_contents); + + google_breakpad::ProcessResult result = + ProcessMicrodump(symbols_file, microdump_contents, state); + + ASSERT_EQ(google_breakpad::PROCESS_OK, result); + ASSERT_TRUE(state->crashed()); + ASSERT_EQ(0, state->requesting_thread()); + ASSERT_EQ(1U, state->threads()->size()); + + ASSERT_EQ(expected_cpu_count, state->system_info()->cpu_count); + ASSERT_EQ("android", state->system_info()->os_short); + ASSERT_EQ("Android", state->system_info()->os); + } + + string files_path_; +}; + +TEST_F(MicrodumpProcessorTest, TestProcess_Invalid) { + ProcessState state; + google_breakpad::ProcessResult result = + ProcessMicrodump("", "This is not a valid microdump", &state); + ASSERT_EQ(google_breakpad::PROCESS_ERROR_NO_THREAD_LIST, result); +} + +TEST_F(MicrodumpProcessorTest, TestProcess_WithoutCrashReason) { + ProcessState state; + AnalyzeDump("microdump-arm64.dmp", true /* omit_symbols */, + 2 /* expected_cpu_count */, &state); + ASSERT_EQ(state.crash_reason(), ""); + ASSERT_EQ(state.crash_address(), 0x0u); +} + +TEST_F(MicrodumpProcessorTest, TestProcess_WithCrashReason) { + ProcessState state; + AnalyzeDump("microdump-withcrashreason.dmp", true /* omit_symbols */, + 8 /* expected_cpu_count */, &state); + ASSERT_EQ(state.crash_reason(), "SIGTRAP"); + ASSERT_EQ(state.crash_address(), 0x4A7CB000u); +} + +TEST_F(MicrodumpProcessorTest, TestProcess_MissingSymbols) { + ProcessState state; + AnalyzeDump("microdump-arm64.dmp", true /* omit_symbols */, + 2 /* expected_cpu_count */, &state); + + ASSERT_EQ(8U, state.modules()->module_count()); + ASSERT_EQ("arm64", state.system_info()->cpu); + ASSERT_EQ("OS 64 VERSION INFO", state.system_info()->os_version); + ASSERT_EQ(1U, state.threads()->size()); + ASSERT_EQ(11U, state.threads()->at(0)->frames()->size()); + + ASSERT_EQ("", + state.threads()->at(0)->frames()->at(0)->function_name); + ASSERT_EQ("", + state.threads()->at(0)->frames()->at(3)->function_name); +} + +TEST_F(MicrodumpProcessorTest, TestProcess_UnsupportedArch) { + string microdump_contents = + "W/google-breakpad(26491): -----BEGIN BREAKPAD MICRODUMP-----\n" + "W/google-breakpad(26491): O A \"unsupported-arch\"\n" + "W/google-breakpad(26491): S 0 A48BD840 A48BD000 00002000\n"; + + ProcessState state; + + google_breakpad::ProcessResult result = + ProcessMicrodump("", microdump_contents, &state); + + ASSERT_EQ(google_breakpad::PROCESS_ERROR_NO_THREAD_LIST, result); +} + +TEST_F(MicrodumpProcessorTest, TestProcessArm) { + ProcessState state; + AnalyzeDump("microdump-arm.dmp", false /* omit_symbols */, + 2 /* expected_cpu_count*/, &state); + + ASSERT_EQ(6U, state.modules()->module_count()); + ASSERT_EQ("arm", state.system_info()->cpu); + ASSERT_EQ("OpenGL ES 3.0 V@104.0 AU@ (GIT@Id3510ff6dc)", + state.system_info()->gl_version); + ASSERT_EQ("Qualcomm", state.system_info()->gl_vendor); + ASSERT_EQ("Adreno (TM) 330", state.system_info()->gl_renderer); + ASSERT_EQ("OS VERSION INFO", state.system_info()->os_version); + ASSERT_EQ(8U, state.threads()->at(0)->frames()->size()); + ASSERT_EQ("MicrodumpWriterTest_Setup_Test::TestBody", + state.threads()->at(0)->frames()->at(0)->function_name); + ASSERT_EQ("testing::Test::Run", + state.threads()->at(0)->frames()->at(1)->function_name); + ASSERT_EQ("main", + state.threads()->at(0)->frames()->at(6)->function_name); + ASSERT_EQ("breakpad_unittests", + state.threads()->at(0)->frames()->at(6)->module->code_file()); +} + +TEST_F(MicrodumpProcessorTest, TestProcessArm64) { + ProcessState state; + AnalyzeDump("microdump-arm64.dmp", false /* omit_symbols */, + 2 /* expected_cpu_count*/, &state); + + ASSERT_EQ(8U, state.modules()->module_count()); + ASSERT_EQ("arm64", state.system_info()->cpu); + ASSERT_EQ("OS 64 VERSION INFO", state.system_info()->os_version); + ASSERT_EQ(9U, state.threads()->at(0)->frames()->size()); + ASSERT_EQ("MicrodumpWriterTest_Setup_Test::TestBody", + state.threads()->at(0)->frames()->at(0)->function_name); + ASSERT_EQ("testing::Test::Run", + state.threads()->at(0)->frames()->at(2)->function_name); + ASSERT_EQ("main", + state.threads()->at(0)->frames()->at(7)->function_name); + ASSERT_EQ("breakpad_unittests", + state.threads()->at(0)->frames()->at(7)->module->code_file()); +} + +TEST_F(MicrodumpProcessorTest, TestProcessX86) { + ProcessState state; + AnalyzeDump("microdump-x86.dmp", false /* omit_symbols */, + 4 /* expected_cpu_count */, &state); + + ASSERT_EQ(124U, state.modules()->module_count()); + ASSERT_EQ("x86", state.system_info()->cpu); + ASSERT_EQ("asus/WW_Z00A/Z00A:5.0/LRX21V/2.19.40.22_20150627_5104_user:user/" + "release-keys", state.system_info()->os_version); + ASSERT_EQ(17U, state.threads()->at(0)->frames()->size()); + ASSERT_EQ("libc.so", + state.threads()->at(0)->frames()->at(0)->module->debug_file()); + // TODO(mmandlis): Get symbols for the test X86 microdump and test function + // names. +} + +TEST_F(MicrodumpProcessorTest, TestProcessMultiple) { + ProcessState state; + AnalyzeDump("microdump-multiple.dmp", false /* omit_symbols */, + 6 /* expected_cpu_count */, &state); + ASSERT_EQ(156U, state.modules()->module_count()); + ASSERT_EQ("arm", state.system_info()->cpu); + ASSERT_EQ("lge/p1_tmo_us/p1:6.0/MRA58K/1603210524c8d:user/release-keys", + state.system_info()->os_version); + ASSERT_EQ(5U, state.threads()->at(0)->frames()->size()); +} + +TEST_F(MicrodumpProcessorTest, TestProcessMips) { + ProcessState state; + AnalyzeDump("microdump-mips32.dmp", false /* omit_symbols */, + 2 /* expected_cpu_count */, &state); + + ASSERT_EQ(7U, state.modules()->module_count()); + ASSERT_EQ("mips", state.system_info()->cpu); + ASSERT_EQ("3.0.8-g893bf16 #7 SMP PREEMPT Fri Jul 10 15:20:59 PDT 2015", + state.system_info()->os_version); + ASSERT_EQ(4U, state.threads()->at(0)->frames()->size()); + + ASSERT_EQ("blaTest", + state.threads()->at(0)->frames()->at(0)->function_name); + ASSERT_EQ("Crash", + state.threads()->at(0)->frames()->at(1)->function_name); + ASSERT_EQ("main", + state.threads()->at(0)->frames()->at(2)->function_name); + ASSERT_EQ("crash_example", + state.threads()->at(0)->frames()->at(0)->module->debug_file()); +} + +TEST_F(MicrodumpProcessorTest, TestProcessMips64) { + ProcessState state; + AnalyzeDump("microdump-mips64.dmp", false /* omit_symbols */, + 1 /* expected_cpu_count */, &state); + + ASSERT_EQ(8U, state.modules()->module_count()); + ASSERT_EQ("mips64", state.system_info()->cpu); + ASSERT_EQ("3.10.0-gf185e20 #112 PREEMPT Mon Oct 5 11:12:49 PDT 2015", + state.system_info()->os_version); + ASSERT_EQ(4U, state.threads()->at(0)->frames()->size()); + + ASSERT_EQ("blaTest", + state.threads()->at(0)->frames()->at(0)->function_name); + ASSERT_EQ("Crash", + state.threads()->at(0)->frames()->at(1)->function_name); + ASSERT_EQ("main", + state.threads()->at(0)->frames()->at(2)->function_name); + ASSERT_EQ("crash_example", + state.threads()->at(0)->frames()->at(0)->module->debug_file()); +} + +} // namespace + +int main(int argc, char* argv[]) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} |