diff options
Diffstat (limited to 'src/processor/stackwalker_arm_unittest.cc')
-rw-r--r-- | src/processor/stackwalker_arm_unittest.cc | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/src/processor/stackwalker_arm_unittest.cc b/src/processor/stackwalker_arm_unittest.cc index b50f4e99..c73322e6 100644 --- a/src/processor/stackwalker_arm_unittest.cc +++ b/src/processor/stackwalker_arm_unittest.cc @@ -54,6 +54,7 @@ using google_breakpad::CodeModule; using google_breakpad::StackFrameSymbolizer; using google_breakpad::StackFrame; using google_breakpad::StackFrameARM; +using google_breakpad::Stackwalker; using google_breakpad::StackwalkerARM; using google_breakpad::SystemInfo; using google_breakpad::WindowsFrameInfo; @@ -97,6 +98,9 @@ class StackwalkerARMFixture { // Avoid GMOCK WARNING "Uninteresting mock function call - returning // directly" for FreeSymbolData(). EXPECT_CALL(supplier, FreeSymbolData(_)).Times(AnyNumber()); + + // Reset max_frames_scanned since it's static. + Stackwalker::set_max_frames_scanned(1024); } // Set the Breakpad symbol information that supplier should return for @@ -406,6 +410,61 @@ TEST_F(GetCallerFrame, ScanFirstFrame) { EXPECT_EQ(frame1_sp.Value(), frame1->context.iregs[MD_CONTEXT_ARM_REG_SP]); } +// Test that set_max_frames_scanned prevents using stack scanning +// to find caller frames. +TEST_F(GetCallerFrame, ScanningNotAllowed) { + // When the stack walker resorts to scanning the stack, + // only addresses located within loaded modules are + // considered valid return addresses. + stack_section.start() = 0x80000000; + uint32_t return_address1 = 0x50000100; + uint32_t return_address2 = 0x50000900; + Label frame1_sp, frame2_sp; + stack_section + // frame 0 + .Append(16, 0) // space + + .D32(0x40090000) // junk that's not + .D32(0x60000000) // a return address + + .D32(return_address1) // actual return address + // frame 1 + .Mark(&frame1_sp) + .Append(16, 0) // space + + .D32(0xF0000000) // more junk + .D32(0x0000000D) + + .D32(return_address2) // actual return address + // frame 2 + .Mark(&frame2_sp) + .Append(32, 0); // end of stack + RegionFromSection(); + + raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40005510; + raw_context.iregs[MD_CONTEXT_ARM_REG_SP] = stack_section.start().Value(); + + StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); + StackwalkerARM walker(&system_info, &raw_context, -1, &stack_region, &modules, + &frame_symbolizer); + Stackwalker::set_max_frames_scanned(0); + + vector<const CodeModule*> modules_without_symbols; + vector<const CodeModule*> modules_with_corrupt_symbols; + ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, + &modules_with_corrupt_symbols)); + ASSERT_EQ(1U, modules_without_symbols.size()); + ASSERT_EQ("module1", modules_without_symbols[0]->debug_file()); + ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); + frames = call_stack.frames(); + ASSERT_EQ(1U, frames->size()); + + StackFrameARM *frame0 = static_cast<StackFrameARM *>(frames->at(0)); + EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); + ASSERT_EQ(StackFrameARM::CONTEXT_VALID_ALL, frame0->context_validity); + EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context))); +} + struct CFIFixture: public StackwalkerARMFixture { CFIFixture() { // Provide a bunch of STACK CFI records; we'll walk to the caller |