Loading libunwindstack/Unwinder.cpp +4 −1 Original line number Diff line number Diff line Loading @@ -63,7 +63,10 @@ void Unwinder::FillInDexFrame() { if (info != nullptr) { frame->map_start = info->start; frame->map_end = info->end; frame->map_elf_start_offset = info->elf_start_offset; // Since this is a dex file frame, the elf_start_offset is not set // by any of the normal code paths. Use the offset of the map since // that matches the actual offset. frame->map_elf_start_offset = info->offset; frame->map_exact_offset = info->offset; frame->map_load_bias = info->load_bias; frame->map_flags = info->flags; Loading libunwindstack/tests/UnwinderTest.cpp +48 −0 Original line number Diff line number Diff line Loading @@ -132,6 +132,10 @@ class UnwinderTest : public ::testing::Test { const auto& info6 = *--maps_->end(); info6->memory_backed_elf = true; AddMapInfo(0xd0000, 0xd1000, 0x1000, PROT_READ | PROT_WRITE | PROT_EXEC, "/fake/fake.apk"); const auto& info7 = *--maps_->end(); info7->load_bias = 0; process_memory_.reset(new MemoryFake); } Loading Loading @@ -1015,6 +1019,50 @@ TEST_F(UnwinderTest, dex_pc_in_map) { EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags); } TEST_F(UnwinderTest, dex_pc_in_map_non_zero_offset) { ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0)); regs_.set_pc(0x1000); regs_.set_sp(0x10000); regs_.FakeSetDexPc(0xd0400); Unwinder unwinder(64, maps_.get(), ®s_, process_memory_); unwinder.Unwind(); EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode()); 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(0x400U, frame->rel_pc); EXPECT_EQ(0xd0400U, frame->pc); EXPECT_EQ(0x10000U, frame->sp); EXPECT_EQ("", frame->function_name); EXPECT_EQ(0U, frame->function_offset); EXPECT_EQ("/fake/fake.apk", frame->map_name); EXPECT_EQ(0x1000U, frame->map_elf_start_offset); EXPECT_EQ(0x1000U, frame->map_exact_offset); EXPECT_EQ(0xd0000U, frame->map_start); EXPECT_EQ(0xd1000U, frame->map_end); EXPECT_EQ(0U, frame->map_load_bias); EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, 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_not_in_map) { ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0)); regs_.set_pc(0x1000); Loading Loading
libunwindstack/Unwinder.cpp +4 −1 Original line number Diff line number Diff line Loading @@ -63,7 +63,10 @@ void Unwinder::FillInDexFrame() { if (info != nullptr) { frame->map_start = info->start; frame->map_end = info->end; frame->map_elf_start_offset = info->elf_start_offset; // Since this is a dex file frame, the elf_start_offset is not set // by any of the normal code paths. Use the offset of the map since // that matches the actual offset. frame->map_elf_start_offset = info->offset; frame->map_exact_offset = info->offset; frame->map_load_bias = info->load_bias; frame->map_flags = info->flags; Loading
libunwindstack/tests/UnwinderTest.cpp +48 −0 Original line number Diff line number Diff line Loading @@ -132,6 +132,10 @@ class UnwinderTest : public ::testing::Test { const auto& info6 = *--maps_->end(); info6->memory_backed_elf = true; AddMapInfo(0xd0000, 0xd1000, 0x1000, PROT_READ | PROT_WRITE | PROT_EXEC, "/fake/fake.apk"); const auto& info7 = *--maps_->end(); info7->load_bias = 0; process_memory_.reset(new MemoryFake); } Loading Loading @@ -1015,6 +1019,50 @@ TEST_F(UnwinderTest, dex_pc_in_map) { EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags); } TEST_F(UnwinderTest, dex_pc_in_map_non_zero_offset) { ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0)); regs_.set_pc(0x1000); regs_.set_sp(0x10000); regs_.FakeSetDexPc(0xd0400); Unwinder unwinder(64, maps_.get(), ®s_, process_memory_); unwinder.Unwind(); EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode()); 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(0x400U, frame->rel_pc); EXPECT_EQ(0xd0400U, frame->pc); EXPECT_EQ(0x10000U, frame->sp); EXPECT_EQ("", frame->function_name); EXPECT_EQ(0U, frame->function_offset); EXPECT_EQ("/fake/fake.apk", frame->map_name); EXPECT_EQ(0x1000U, frame->map_elf_start_offset); EXPECT_EQ(0x1000U, frame->map_exact_offset); EXPECT_EQ(0xd0000U, frame->map_start); EXPECT_EQ(0xd1000U, frame->map_end); EXPECT_EQ(0U, frame->map_load_bias); EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, 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_not_in_map) { ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0)); regs_.set_pc(0x1000); Loading