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

Commit 2733708c authored by Christopher Ferris's avatar Christopher Ferris Committed by Gerrit Code Review
Browse files

Merge "Add ability to skip function name resolution."

parents 9b4d7dd5 e4b3a6aa
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@ bool Backtrace::Unwind(unwindstack::Regs* regs, BacktraceMap* back_map,
  auto process_memory = stack_map->process_memory();
  unwindstack::Unwinder unwinder(MAX_BACKTRACE_FRAMES + num_ignore_frames, stack_map->stack_maps(),
                                 regs, stack_map->process_memory());
  unwinder.SetResolveNames(stack_map->ResolveNames());
  if (stack_map->GetJitDebug() != nullptr) {
    unwinder.SetJitDebug(stack_map->GetJitDebug(), regs->Arch());
  }
+8 −0
Original line number Diff line number Diff line
@@ -154,6 +154,13 @@ public:

  const std::vector<std::string>& GetSuffixesToIgnore() { return suffixes_to_ignore_; }

  // Disabling the resolving of names results in the function name being
  // set to an empty string and the function offset being set to zero
  // in the frame data when unwinding.
  void SetResolveNames(bool resolve) { resolve_names_ = resolve; }

  bool ResolveNames() { return resolve_names_; }

 protected:
  BacktraceMap(pid_t pid);

@@ -164,6 +171,7 @@ public:
  pid_t pid_;
  std::deque<backtrace_map_t> maps_;
  std::vector<std::string> suffixes_to_ignore_;
  bool resolve_names_ = true;
};

class ScopedBacktraceMapIteratorLock {
+6 −1
Original line number Diff line number Diff line
@@ -68,6 +68,10 @@ void Unwinder::FillInDexFrame() {
    return;
  }

  if (!resolve_names_) {
    return;
  }

#if !defined(NO_LIBDEXFILE_SUPPORT)
  if (dex_files_ == nullptr) {
    return;
@@ -100,7 +104,8 @@ void Unwinder::FillInFrame(MapInfo* map_info, Elf* elf, uint64_t adjusted_rel_pc
  frame->map_flags = map_info->flags;
  frame->map_load_bias = elf->GetLoadBias();

  if (!elf->GetFunctionName(func_pc, &frame->function_name, &frame->function_offset)) {
  if (!resolve_names_ ||
      !elf->GetFunctionName(func_pc, &frame->function_name, &frame->function_offset)) {
    frame->function_name = "";
    frame->function_offset = 0;
  }
+5 −0
Original line number Diff line number Diff line
@@ -75,6 +75,10 @@ class Unwinder {

  void SetJitDebug(JitDebug* jit_debug, ArchEnum arch);

  // Disabling the resolving of names results in the function name being
  // set to an empty string and the function offset being set to zero.
  void SetResolveNames(bool resolve) { resolve_names_ = resolve; }

#if !defined(NO_LIBDEXFILE_SUPPORT)
  void SetDexFiles(DexFiles* dex_files, ArchEnum arch);
#endif
@@ -95,6 +99,7 @@ class Unwinder {
#if !defined(NO_LIBDEXFILE_SUPPORT)
  DexFiles* dex_files_ = nullptr;
#endif
  bool resolve_names_ = true;
  ErrorData last_error_;
};

+61 −0
Original line number Diff line number Diff line
@@ -196,6 +196,67 @@ TEST_F(UnwinderTest, multiple_frames) {
  EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
}

TEST_F(UnwinderTest, multiple_frames_dont_resolve_names) {
  ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
  ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
  ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));

  regs_.FakeSetPc(0x1000);
  regs_.FakeSetSp(0x10000);
  ElfInterfaceFake::FakePushStepData(StepData(0x1102, 0x10010, false));
  ElfInterfaceFake::FakePushStepData(StepData(0x1202, 0x10020, false));
  ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));

  Unwinder unwinder(64, &maps_, &regs_, process_memory_);
  unwinder.SetResolveNames(false);
  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(0U, frame->rel_pc);
  EXPECT_EQ(0x1000U, frame->pc);
  EXPECT_EQ(0x10000U, frame->sp);
  EXPECT_EQ("", 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()[1];
  EXPECT_EQ(1U, frame->num);
  EXPECT_EQ(0x100U, frame->rel_pc);
  EXPECT_EQ(0x1100U, frame->pc);
  EXPECT_EQ(0x10010U, frame->sp);
  EXPECT_EQ("", 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(0x200U, frame->rel_pc);
  EXPECT_EQ(0x1200U, frame->pc);
  EXPECT_EQ(0x10020U, frame->sp);
  EXPECT_EQ("", 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);
}

TEST_F(UnwinderTest, non_zero_load_bias) {
  ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));