Loading libunwindstack/Unwinder.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -175,6 +175,8 @@ void Unwinder::Unwind(const std::vector<std::string>* initial_map_names_to_skip, if (regs_->dex_pc() != 0) { // Add a frame to represent the dex file. FillInDexFrame(); // Clear the dex pc so that we don't repeat this frame later. regs_->set_dex_pc(0); } FillInFrame(map_info, elf, adjusted_rel_pc, adjusted_pc); Loading libunwindstack/tests/UnwinderTest.cpp +58 −0 Original line number Diff line number Diff line Loading @@ -752,6 +752,64 @@ TEST_F(UnwinderTest, dex_pc_not_in_map) { 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)); regs_.FakeSetPc(0x1000); regs_.FakeSetSp(0x10000); regs_.FakeSetDexPc(0xa3400); ElfInterfaceFake::FakePushStepData(StepData(0x33402, 0x10010, false)); ElfInterfaceFake::FakePushStepData(StepData(0, 0, true)); Unwinder unwinder(64, &maps_, ®s_, process_memory_); unwinder.Unwind(); EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode()); ASSERT_EQ(3U, unwinder.NumFrames()); auto* frame = &unwinder.frames()[0]; EXPECT_EQ(0U, frame->num); EXPECT_EQ(0x400U, frame->rel_pc); EXPECT_EQ(0xa3400U, frame->pc); EXPECT_EQ(0x10000U, frame->sp); EXPECT_EQ("", frame->function_name); EXPECT_EQ(0U, frame->function_offset); EXPECT_EQ("/fake/fake.vdex", frame->map_name); EXPECT_EQ(0U, frame->map_offset); EXPECT_EQ(0xa3000U, frame->map_start); EXPECT_EQ(0xa4000U, 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_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); frame = &unwinder.frames()[2]; EXPECT_EQ(2U, frame->num); EXPECT_EQ(0x400U, frame->rel_pc); EXPECT_EQ(0x33400U, frame->pc); EXPECT_EQ(0x10010U, frame->sp); EXPECT_EQ("Frame1", frame->function_name); EXPECT_EQ(1U, frame->function_offset); EXPECT_EQ("/fake/compressed.so", frame->map_name); EXPECT_EQ(0U, frame->map_offset); EXPECT_EQ(0x33000U, frame->map_start); EXPECT_EQ(0x34000U, frame->map_end); EXPECT_EQ(0U, frame->map_load_bias); EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags); } // Verify format frame code. TEST_F(UnwinderTest, format_frame_static) { FrameData frame; Loading Loading
libunwindstack/Unwinder.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -175,6 +175,8 @@ void Unwinder::Unwind(const std::vector<std::string>* initial_map_names_to_skip, if (regs_->dex_pc() != 0) { // Add a frame to represent the dex file. FillInDexFrame(); // Clear the dex pc so that we don't repeat this frame later. regs_->set_dex_pc(0); } FillInFrame(map_info, elf, adjusted_rel_pc, adjusted_pc); Loading
libunwindstack/tests/UnwinderTest.cpp +58 −0 Original line number Diff line number Diff line Loading @@ -752,6 +752,64 @@ TEST_F(UnwinderTest, dex_pc_not_in_map) { 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)); regs_.FakeSetPc(0x1000); regs_.FakeSetSp(0x10000); regs_.FakeSetDexPc(0xa3400); ElfInterfaceFake::FakePushStepData(StepData(0x33402, 0x10010, false)); ElfInterfaceFake::FakePushStepData(StepData(0, 0, true)); Unwinder unwinder(64, &maps_, ®s_, process_memory_); unwinder.Unwind(); EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode()); ASSERT_EQ(3U, unwinder.NumFrames()); auto* frame = &unwinder.frames()[0]; EXPECT_EQ(0U, frame->num); EXPECT_EQ(0x400U, frame->rel_pc); EXPECT_EQ(0xa3400U, frame->pc); EXPECT_EQ(0x10000U, frame->sp); EXPECT_EQ("", frame->function_name); EXPECT_EQ(0U, frame->function_offset); EXPECT_EQ("/fake/fake.vdex", frame->map_name); EXPECT_EQ(0U, frame->map_offset); EXPECT_EQ(0xa3000U, frame->map_start); EXPECT_EQ(0xa4000U, 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_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); frame = &unwinder.frames()[2]; EXPECT_EQ(2U, frame->num); EXPECT_EQ(0x400U, frame->rel_pc); EXPECT_EQ(0x33400U, frame->pc); EXPECT_EQ(0x10010U, frame->sp); EXPECT_EQ("Frame1", frame->function_name); EXPECT_EQ(1U, frame->function_offset); EXPECT_EQ("/fake/compressed.so", frame->map_name); EXPECT_EQ(0U, frame->map_offset); EXPECT_EQ(0x33000U, frame->map_start); EXPECT_EQ(0x34000U, frame->map_end); EXPECT_EQ(0U, frame->map_load_bias); EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags); } // Verify format frame code. TEST_F(UnwinderTest, format_frame_static) { FrameData frame; Loading