diff options
author | Christopher Ferris <cferris@google.com> | 2020-08-27 22:17:09 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2020-08-27 22:17:09 +0000 |
commit | db503ecba29ac03576960e8471e0094be5decd1d (patch) | |
tree | 43fd7be4910759890916bed48c91b4b100997ba4 | |
parent | 025321862c321d00a4054222be61e2455cfb8509 (diff) | |
parent | 8b0cabe36fe1fe62a7456e7e5abb9ab34437dae1 (diff) |
Merge "Fix nullptr dereference." am: bb81b77895 am: 1300d1cfe9 am: 8b0cabe36f
Original change: https://android-review.googlesource.com/c/platform/system/core/+/1413809
Change-Id: Icaa802bc11ff298b765cb4ff93f8c8ff7ad7d309
-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 b904632ef5..4e7096ec1b 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 d10af2f0b7..ddd4b4d1b0 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)); |