Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a4bdb984 authored by Christopher Ferris's avatar Christopher Ferris
Browse files

Display offsets for dex frames.

When adding a dex frame, no offset is ever printed even if the dex data
is coming from a non-zero offset map. Fixed so an offset is printed
in this case.

Previous the line looked like this:

  #17 pc 0000000000500d7a  /product/app/GoogleCamera/GoogleCamera.apk (com.google.android.libraries.camera.async.AndroidPriorityThread.run+10)

Now looks like:

  #17 pc 0000000000500d7a  /product/app/GoogleCamera/GoogleCamera.apk (offset 0x11d0000) (com.google.android.libraries.camera.async.AndroidPriorityThread.run+10)

Add new unit test for this case.

Bug: 134420076

Test: Wrote new unit test, and verified a non-zero offset for dex file
Test: data results in a frame with a non-zero offset.
Change-Id: I58c134fda4fad5456ca0f1723192667a1ca5d509
parent 41f690ba
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -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;
+48 −0
Original line number Diff line number Diff line
@@ -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);
  }

@@ -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(), &regs_, 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);