Home | History | Annotate | Download | only in processor
      1 // Copyright (c) 2013, Google Inc.
      2 // All rights reserved.
      3 //
      4 // Redistribution and use in source and binary forms, with or without
      5 // modification, are permitted provided that the following conditions are
      6 // met:
      7 //
      8 //     * Redistributions of source code must retain the above copyright
      9 // notice, this list of conditions and the following disclaimer.
     10 //     * Redistributions in binary form must reproduce the above
     11 // copyright notice, this list of conditions and the following disclaimer
     12 // in the documentation and/or other materials provided with the
     13 // distribution.
     14 //     * Neither the name of Google Inc. nor the names of its
     15 // contributors may be used to endorse or promote products derived from
     16 // this software without specific prior written permission.
     17 //
     18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29 
     30 // stackwalker_address_list_unittest.cc: Unit tests for the
     31 // StackwalkerAddressList class.
     32 //
     33 // Author: Chris Hamilton <chrisha (at) chromium.org>
     34 
     35 #include <string>
     36 #include <vector>
     37 
     38 #include "breakpad_googletest_includes.h"
     39 #include "common/using_std_string.h"
     40 #include "google_breakpad/common/minidump_format.h"
     41 #include "google_breakpad/processor/basic_source_line_resolver.h"
     42 #include "google_breakpad/processor/call_stack.h"
     43 #include "google_breakpad/processor/code_module.h"
     44 #include "google_breakpad/processor/source_line_resolver_interface.h"
     45 #include "google_breakpad/processor/stack_frame.h"
     46 #include "processor/stackwalker_unittest_utils.h"
     47 #include "processor/stackwalker_address_list.h"
     48 
     49 using google_breakpad::BasicSourceLineResolver;
     50 using google_breakpad::CallStack;
     51 using google_breakpad::CodeModule;
     52 using google_breakpad::StackFrameSymbolizer;
     53 using google_breakpad::StackFrame;
     54 using google_breakpad::Stackwalker;
     55 using google_breakpad::StackwalkerAddressList;
     56 using std::vector;
     57 using testing::_;
     58 using testing::AnyNumber;
     59 using testing::Return;
     60 using testing::SetArgumentPointee;
     61 
     62 #define arraysize(f) (sizeof(f) / sizeof(*f))
     63 
     64 // Addresses and sizes of a couple dummy modules.
     65 uint64_t kModule1Base = 0x40000000;
     66 uint64_t kModule1Size = 0x10000;
     67 uint64_t kModule2Base = 0x50000000;
     68 uint64_t kModule2Size = 0x10000;
     69 
     70 // A handful of addresses that lie within the modules above.
     71 const uint64_t kDummyFrames[] = {
     72     0x50003000, 0x50002000, 0x50001000, 0x40002000, 0x40001000 };
     73 
     74 class StackwalkerAddressListTest : public testing::Test {
     75  public:
     76   StackwalkerAddressListTest()
     77     : // Give the two modules reasonable standard locations and names
     78       // for tests to play with.
     79       module1(kModule1Base, kModule1Size, "module1", "version1"),
     80       module2(kModule2Base, kModule2Size, "module2", "version2") {
     81     // Create some modules with some stock debugging information.
     82     modules.Add(&module1);
     83     modules.Add(&module2);
     84 
     85     // By default, none of the modules have symbol info; call
     86     // SetModuleSymbols to override this.
     87     EXPECT_CALL(supplier, GetCStringSymbolData(_, _, _, _, _))
     88       .WillRepeatedly(Return(MockSymbolSupplier::NOT_FOUND));
     89 
     90     // Avoid GMOCK WARNING "Uninteresting mock function call - returning
     91     // directly" for FreeSymbolData().
     92     EXPECT_CALL(supplier, FreeSymbolData(_)).Times(AnyNumber());
     93   }
     94 
     95   // Set the Breakpad symbol information that supplier should return for
     96   // MODULE to INFO.
     97   void SetModuleSymbols(MockCodeModule *module, const string &info) {
     98     size_t buffer_size;
     99     char *buffer = supplier.CopySymbolDataAndOwnTheCopy(info, &buffer_size);
    100     EXPECT_CALL(supplier, GetCStringSymbolData(module, NULL, _, _, _))
    101       .WillRepeatedly(DoAll(SetArgumentPointee<3>(buffer),
    102                             SetArgumentPointee<4>(buffer_size),
    103                             Return(MockSymbolSupplier::FOUND)));
    104   }
    105 
    106   void CheckCallStack(const CallStack& call_stack) {
    107     const std::vector<StackFrame*>* frames = call_stack.frames();
    108     ASSERT_EQ(arraysize(kDummyFrames), frames->size());
    109     for (size_t i = 0; i < arraysize(kDummyFrames); ++i) {
    110       ASSERT_EQ(kDummyFrames[i], frames->at(i)->instruction);
    111       ASSERT_EQ(StackFrame::FRAME_TRUST_PREWALKED, frames->at(i)->trust);
    112     }
    113     ASSERT_EQ(static_cast<const CodeModule*>(&module2), frames->at(0)->module);
    114     ASSERT_EQ(static_cast<const CodeModule*>(&module2), frames->at(1)->module);
    115     ASSERT_EQ(static_cast<const CodeModule*>(&module2), frames->at(2)->module);
    116     ASSERT_EQ(static_cast<const CodeModule*>(&module1), frames->at(3)->module);
    117     ASSERT_EQ(static_cast<const CodeModule*>(&module1), frames->at(4)->module);
    118   }
    119 
    120   MockCodeModule module1;
    121   MockCodeModule module2;
    122   MockCodeModules modules;
    123   MockSymbolSupplier supplier;
    124   BasicSourceLineResolver resolver;
    125 };
    126 
    127 TEST_F(StackwalkerAddressListTest, ScanWithoutSymbols) {
    128   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
    129   StackwalkerAddressList walker(kDummyFrames, arraysize(kDummyFrames),
    130                          &modules, &frame_symbolizer);
    131 
    132   CallStack call_stack;
    133   vector<const CodeModule*> modules_without_symbols;
    134   vector<const CodeModule*> modules_with_corrupt_symbols;
    135   ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
    136                           &modules_with_corrupt_symbols));
    137 
    138   // The stack starts in module2, so we expect that to be the first module
    139   // found without symbols.
    140   ASSERT_EQ(2U, modules_without_symbols.size());
    141   ASSERT_EQ("module2", modules_without_symbols[0]->debug_file());
    142   ASSERT_EQ("module1", modules_without_symbols[1]->debug_file());
    143   ASSERT_EQ(0u, modules_with_corrupt_symbols.size());
    144 
    145   ASSERT_NO_FATAL_FAILURE(CheckCallStack(call_stack));
    146 }
    147 
    148 TEST_F(StackwalkerAddressListTest, ScanWithSymbols) {
    149   // File    : FILE number(dex) name
    150   // Function: FUNC address(hex) size(hex) parameter_size(hex) name
    151   // Line    : address(hex) size(hex) line(dec) filenum(dec)
    152   SetModuleSymbols(&module2,
    153                    "FILE 1 module2.cc\n"
    154                    "FUNC 3000 100 10 mod2func3\n"
    155                    "3000 10 1  1\n"
    156                    "FUNC 2000 200 10 mod2func2\n"
    157                    "FUNC 1000 300 10 mod2func1\n");
    158   SetModuleSymbols(&module1,
    159                    "FUNC 2000 200 10 mod1func2\n"
    160                    "FUNC 1000 300 10 mod1func1\n");
    161 
    162   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
    163   StackwalkerAddressList walker(kDummyFrames, arraysize(kDummyFrames),
    164                          &modules, &frame_symbolizer);
    165 
    166   CallStack call_stack;
    167   vector<const CodeModule*> modules_without_symbols;
    168   vector<const CodeModule*> modules_with_corrupt_symbols;
    169   ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
    170                           &modules_with_corrupt_symbols));
    171 
    172   ASSERT_EQ(0u, modules_without_symbols.size());
    173   ASSERT_EQ(0u, modules_with_corrupt_symbols.size());
    174 
    175   ASSERT_NO_FATAL_FAILURE(CheckCallStack(call_stack));
    176 
    177   const std::vector<StackFrame*>* frames = call_stack.frames();
    178 
    179   // We have full file/line information for the first function call.
    180   ASSERT_EQ("mod2func3", frames->at(0)->function_name);
    181   ASSERT_EQ(0x50003000u, frames->at(0)->function_base);
    182   ASSERT_EQ("module2.cc", frames->at(0)->source_file_name);
    183   ASSERT_EQ(1, frames->at(0)->source_line);
    184   ASSERT_EQ(0x50003000u, frames->at(0)->source_line_base);
    185 
    186   ASSERT_EQ("mod2func2", frames->at(1)->function_name);
    187   ASSERT_EQ(0x50002000u, frames->at(1)->function_base);
    188 
    189   ASSERT_EQ("mod2func1", frames->at(2)->function_name);
    190   ASSERT_EQ(0x50001000u, frames->at(2)->function_base);
    191 
    192   ASSERT_EQ("mod1func2", frames->at(3)->function_name);
    193   ASSERT_EQ(0x40002000u, frames->at(3)->function_base);
    194 
    195   ASSERT_EQ("mod1func1", frames->at(4)->function_name);
    196   ASSERT_EQ(0x40001000u, frames->at(4)->function_base);
    197 }
    198