diff options
| author | David Srbecky <dsrbecky@google.com> | 2018-03-14 21:30:25 +0000 |
|---|---|---|
| committer | Christopher Ferris <cferris@google.com> | 2018-03-29 14:47:13 +0000 |
| commit | 3386ebade2d28fd3ef68c576bb0375bd226a1320 (patch) | |
| tree | 53f2e511a1e7b507239ab5c89cce0c50df474636 /libunwindstack/tests/DwarfSectionTest.cpp | |
| parent | 324e27d284ef5061746a79ae22ed608460c985e9 (diff) | |
| download | system_core-3386ebade2d28fd3ef68c576bb0375bd226a1320.tar.gz system_core-3386ebade2d28fd3ef68c576bb0375bd226a1320.tar.bz2 system_core-3386ebade2d28fd3ef68c576bb0375bd226a1320.zip | |
Cache DWARF location rules for a given pc.
Decoding the DWARF opcodes is expensive so make sure we cache it.
This speeds unwinding in simpleperf by over a factor of 3x.
Add unit tests for this new behavior.
Bug: 77258731
Test: libbacktrace/libunwindstack unit tests on host and target.
Test: Ran debuggerd -b on various processes on target.
Change-Id: Ia516c0fa5d3e5f76746190bb4b6fdf49fd1c9388
Diffstat (limited to 'libunwindstack/tests/DwarfSectionTest.cpp')
| -rw-r--r-- | libunwindstack/tests/DwarfSectionTest.cpp | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/libunwindstack/tests/DwarfSectionTest.cpp b/libunwindstack/tests/DwarfSectionTest.cpp index 3fcd2b61f..071d2dfa3 100644 --- a/libunwindstack/tests/DwarfSectionTest.cpp +++ b/libunwindstack/tests/DwarfSectionTest.cpp @@ -165,4 +165,72 @@ TEST_F(DwarfSectionTest, Step_pass) { ASSERT_TRUE(mock_section.Step(0x1000, nullptr, &process, &finished)); } +static bool MockGetCfaLocationInfo(::testing::Unused, const DwarfFde* fde, + dwarf_loc_regs_t* loc_regs) { + loc_regs->pc_start = fde->pc_start; + loc_regs->pc_end = fde->pc_end; + return true; +} + +TEST_F(DwarfSectionTest, Step_cache) { + MockDwarfSection mock_section(&memory_); + + DwarfCie cie{}; + DwarfFde fde{}; + fde.pc_start = 0x500; + fde.pc_end = 0x2000; + fde.cie = &cie; + + EXPECT_CALL(mock_section, GetFdeOffsetFromPc(0x1000, ::testing::_)) + .WillOnce(::testing::Return(true)); + EXPECT_CALL(mock_section, GetFdeFromOffset(::testing::_)).WillOnce(::testing::Return(&fde)); + + EXPECT_CALL(mock_section, GetCfaLocationInfo(0x1000, &fde, ::testing::_)) + .WillOnce(::testing::Invoke(MockGetCfaLocationInfo)); + + MemoryFake process; + EXPECT_CALL(mock_section, Eval(&cie, &process, ::testing::_, nullptr, ::testing::_)) + .WillRepeatedly(::testing::Return(true)); + + bool finished; + ASSERT_TRUE(mock_section.Step(0x1000, nullptr, &process, &finished)); + ASSERT_TRUE(mock_section.Step(0x1000, nullptr, &process, &finished)); + ASSERT_TRUE(mock_section.Step(0x1500, nullptr, &process, &finished)); +} + +TEST_F(DwarfSectionTest, Step_cache_not_in_pc) { + MockDwarfSection mock_section(&memory_); + + DwarfCie cie{}; + DwarfFde fde0{}; + fde0.pc_start = 0x1000; + fde0.pc_end = 0x2000; + fde0.cie = &cie; + EXPECT_CALL(mock_section, GetFdeOffsetFromPc(0x1000, ::testing::_)) + .WillOnce(::testing::Return(true)); + EXPECT_CALL(mock_section, GetFdeFromOffset(::testing::_)).WillOnce(::testing::Return(&fde0)); + EXPECT_CALL(mock_section, GetCfaLocationInfo(0x1000, &fde0, ::testing::_)) + .WillOnce(::testing::Invoke(MockGetCfaLocationInfo)); + + MemoryFake process; + EXPECT_CALL(mock_section, Eval(&cie, &process, ::testing::_, nullptr, ::testing::_)) + .WillRepeatedly(::testing::Return(true)); + + bool finished; + ASSERT_TRUE(mock_section.Step(0x1000, nullptr, &process, &finished)); + + DwarfFde fde1{}; + fde1.pc_start = 0x500; + fde1.pc_end = 0x800; + fde1.cie = &cie; + EXPECT_CALL(mock_section, GetFdeOffsetFromPc(0x600, ::testing::_)) + .WillOnce(::testing::Return(true)); + EXPECT_CALL(mock_section, GetFdeFromOffset(::testing::_)).WillOnce(::testing::Return(&fde1)); + EXPECT_CALL(mock_section, GetCfaLocationInfo(0x600, &fde1, ::testing::_)) + .WillOnce(::testing::Invoke(MockGetCfaLocationInfo)); + + ASSERT_TRUE(mock_section.Step(0x600, nullptr, &process, &finished)); + ASSERT_TRUE(mock_section.Step(0x700, nullptr, &process, &finished)); +} + } // namespace unwindstack |
