diff options
author | ted.mielczarek@gmail.com <ted.mielczarek@gmail.com@4c0a9323-5329-0410-9bdc-e9ce6186880e> | 2013-08-19 18:31:51 +0000 |
---|---|---|
committer | ted.mielczarek@gmail.com <ted.mielczarek@gmail.com@4c0a9323-5329-0410-9bdc-e9ce6186880e> | 2013-08-19 18:31:51 +0000 |
commit | 0510e34cbfe1b920b968c33e83101bed49c47aeb (patch) | |
tree | 3cc4bfb4e3c4bcd5a90599c7534116fef0c89426 /src/processor/stackwalker_amd64_unittest.cc | |
parent | Enable the SIGABRT handler on desktop OS X (diff) | |
download | breakpad-0510e34cbfe1b920b968c33e83101bed49c47aeb.tar.xz |
Allow setting a limit on the number of frames to be recovered by stack scanning.
Patch by Julian Seward <jseward@acm.org> R=ted at https://bugzilla.mozilla.org/show_bug.cgi?id=894264
git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1206 4c0a9323-5329-0410-9bdc-e9ce6186880e
Diffstat (limited to 'src/processor/stackwalker_amd64_unittest.cc')
-rw-r--r-- | src/processor/stackwalker_amd64_unittest.cc | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/src/processor/stackwalker_amd64_unittest.cc b/src/processor/stackwalker_amd64_unittest.cc index 169316c6..31489106 100644 --- a/src/processor/stackwalker_amd64_unittest.cc +++ b/src/processor/stackwalker_amd64_unittest.cc @@ -53,6 +53,7 @@ using google_breakpad::CodeModule; using google_breakpad::StackFrameSymbolizer; using google_breakpad::StackFrame; using google_breakpad::StackFrameAMD64; +using google_breakpad::Stackwalker; using google_breakpad::StackwalkerAMD64; using google_breakpad::SystemInfo; using google_breakpad::test_assembler::kLittleEndian; @@ -95,6 +96,9 @@ class StackwalkerAMD64Fixture { // 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 @@ -366,6 +370,68 @@ TEST_F(GetCallerFrame, ScanWithFunctionSymbols) { EXPECT_EQ(0x50000000b0000100ULL, frame1->function_base); } +// 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() = 0x8000000080000000ULL; + uint64_t return_address1 = 0x50000000b0000100ULL; + uint64_t return_address2 = 0x50000000b0000900ULL; + Label frame1_sp, frame2_sp, frame1_rbp; + stack_section + // frame 0 + .Append(16, 0) // space + + .D64(0x40000000b0000000ULL) // junk that's not + .D64(0x50000000d0000000ULL) // a return address + + .D64(return_address1) // actual return address + // frame 1 + .Mark(&frame1_sp) + .Append(16, 0) // space + + .D64(0x40000000b0000000ULL) // more junk + .D64(0x50000000d0000000ULL) + + .Mark(&frame1_rbp) + .D64(stack_section.start()) // This is in the right place to be + // a saved rbp, but it's bogus, so + // we shouldn't report it. + + .D64(return_address2) // actual return address + // frame 2 + .Mark(&frame2_sp) + .Append(32, 0); // end of stack + + RegionFromSection(); + + raw_context.rip = 0x40000000c0000200ULL; + raw_context.rbp = frame1_rbp.Value(); + raw_context.rsp = stack_section.start().Value(); + + StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); + StackwalkerAMD64 walker(&system_info, &raw_context, &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()); + + StackFrameAMD64 *frame0 = static_cast<StackFrameAMD64 *>(frames->at(0)); + EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); + ASSERT_EQ(StackFrameAMD64::CONTEXT_VALID_ALL, frame0->context_validity); + EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context))); +} + TEST_F(GetCallerFrame, CallerPushedRBP) { // Functions typically push their %rbp upon entry and set %rbp pointing // there. If stackwalking finds a plausible address for the next frame's |