diff options
author | Christopher Ferris <cferris@google.com> | 2020-08-27 20:58:09 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2020-08-27 20:58:09 +0000 |
commit | bb81b7789504cc1d70f65486f982ea867bb8fd46 (patch) | |
tree | 06f3474897dc472956c05da1e80e2972056c462a | |
parent | e27781db4c88f1e79348cf2d38cbf01010c85145 (diff) | |
parent | afbed690f091956a85484ac1409c9f1b53dd1df0 (diff) | |
download | core-bb81b7789504cc1d70f65486f982ea867bb8fd46.tar.gz |
Merge "Fix nullptr dereference."
-rw-r--r-- | libunwindstack/Unwinder.cpp | 1 | ||||
-rw-r--r-- | libunwindstack/tests/UnwinderTest.cpp | 66 |
2 files changed, 66 insertions, 1 deletions
diff --git a/libunwindstack/Unwinder.cpp b/libunwindstack/Unwinder.cpp index b904632ef..4e7096ec1 100644 --- a/libunwindstack/Unwinder.cpp +++ b/libunwindstack/Unwinder.cpp @@ -76,6 +76,7 @@ void Unwinder::FillInDexFrame() { } else { frame->rel_pc = dex_pc; warnings_ |= WARNING_DEX_PC_NOT_IN_MAP; + return; } if (!resolve_names_) { diff --git a/libunwindstack/tests/UnwinderTest.cpp b/libunwindstack/tests/UnwinderTest.cpp index d10af2f0b..ddd4b4d1b 100644 --- a/libunwindstack/tests/UnwinderTest.cpp +++ b/libunwindstack/tests/UnwinderTest.cpp @@ -57,6 +57,9 @@ class UnwinderTest : public ::testing::Test { static void SetUpTestSuite() { maps_.reset(new Maps); + memory_ = new MemoryFake; + process_memory_.reset(memory_); + ElfFake* elf = new ElfFake(new MemoryFake); ElfInterfaceFake* interface_fake = new ElfInterfaceFake(nullptr); interface_fake->FakeSetBuildID("FAKE"); @@ -136,7 +139,19 @@ class UnwinderTest : public ::testing::Test { const auto& info7 = *--maps_->end(); info7->load_bias = 0; - process_memory_.reset(new MemoryFake); + elf = new ElfFake(new MemoryFake); + interface = new ElfInterfaceFake(nullptr); + elf->FakeSetInterface(interface); + interface->FakeSetGlobalVariable("__dex_debug_descriptor", 0x1800); + interface->FakeSetDataOffset(0x1000); + interface->FakeSetDataVaddrStart(0x1000); + interface->FakeSetDataVaddrEnd(0x3000); + AddMapInfo(0xf0000, 0xf1000, 0, PROT_READ | PROT_WRITE | PROT_EXEC, "/fake/global.so", elf); + AddMapInfo(0xf1000, 0xf9000, 0x1000, PROT_READ | PROT_WRITE, "/fake/global.so"); + memory_->SetData32(0xf180c, 0xf3000); + memory_->SetData32(0xf3000, 0xf4000); + memory_->SetData32(0xf3004, 0xf4000); + memory_->SetData32(0xf3008, 0xf5000); } void SetUp() override { @@ -147,11 +162,13 @@ class UnwinderTest : public ::testing::Test { static std::unique_ptr<Maps> maps_; static RegsFake regs_; + static MemoryFake* memory_; static std::shared_ptr<Memory> process_memory_; }; std::unique_ptr<Maps> UnwinderTest::maps_; RegsFake UnwinderTest::regs_(5); +MemoryFake* UnwinderTest::memory_; std::shared_ptr<Memory> UnwinderTest::process_memory_(nullptr); TEST_F(UnwinderTest, multiple_frames) { @@ -1129,6 +1146,53 @@ TEST_F(UnwinderTest, dex_pc_not_in_map) { EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags); } +TEST_F(UnwinderTest, dex_pc_not_in_map_valid_dex_files) { + ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0)); + regs_.set_pc(0x1000); + regs_.set_sp(0x10000); + regs_.FakeSetDexPc(0x50000); + + DexFiles dex_files(process_memory_); + Unwinder unwinder(64, maps_.get(), ®s_, process_memory_); + unwinder.SetDexFiles(&dex_files, ARCH_ARM); + unwinder.Unwind(); + EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode()); + EXPECT_EQ(WARNING_DEX_PC_NOT_IN_MAP, unwinder.warnings()); + EXPECT_FALSE(unwinder.elf_from_memory_not_file()); + + ASSERT_EQ(2U, unwinder.NumFrames()); + + auto* frame = &unwinder.frames()[0]; + EXPECT_EQ(0U, frame->num); + EXPECT_EQ(0x50000U, frame->rel_pc); + EXPECT_EQ(0x50000U, frame->pc); + EXPECT_EQ(0x10000U, frame->sp); + EXPECT_EQ("", frame->function_name); + EXPECT_EQ(0U, frame->function_offset); + EXPECT_EQ("", frame->map_name); + EXPECT_EQ(0U, frame->map_elf_start_offset); + EXPECT_EQ(0U, frame->map_exact_offset); + EXPECT_EQ(0U, frame->map_start); + EXPECT_EQ(0U, frame->map_end); + EXPECT_EQ(0U, frame->map_load_bias); + EXPECT_EQ(0, frame->map_flags); + + frame = &unwinder.frames()[1]; + EXPECT_EQ(1U, frame->num); + EXPECT_EQ(0U, frame->rel_pc); + EXPECT_EQ(0x1000U, frame->pc); + EXPECT_EQ(0x10000U, frame->sp); + EXPECT_EQ("Frame0", frame->function_name); + EXPECT_EQ(0U, frame->function_offset); + EXPECT_EQ("/system/fake/libc.so", frame->map_name); + EXPECT_EQ(0U, frame->map_elf_start_offset); + EXPECT_EQ(0U, frame->map_exact_offset); + EXPECT_EQ(0x1000U, frame->map_start); + EXPECT_EQ(0x8000U, frame->map_end); + EXPECT_EQ(0U, frame->map_load_bias); + EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags); +} + TEST_F(UnwinderTest, dex_pc_multiple_frames) { ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0)); ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1)); |