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

Commit 432981b9 authored by Christopher Ferris's avatar Christopher Ferris
Browse files

Modify the offline handling interface.

- Add a new function Backtrace::UnwindOffline that takes the stack data.
- Modify BacktraceMap::CreateOffline so it doesn't take the stack data.
  This makes it easier to reuse the map object created this way.

Reusing the map object increases simpleperf speed (unwinds per second) by 50%.

Test: backtrace_test libunwindstack_test
Change-Id: I90cfbae9e50d95d8a0e3cd394b33ba36d65d45f7
parent cdf778f5
Loading
Loading
Loading
Loading
+20 −4
Original line number Original line Diff line number Diff line
@@ -128,6 +128,22 @@ bool Backtrace::Unwind(unwindstack::Regs* regs, BacktraceMap* back_map,
  return true;
  return true;
}
}


bool Backtrace::UnwindOffline(unwindstack::Regs* regs, BacktraceMap* back_map,
                              const backtrace_stackinfo_t& stack,
                              std::vector<backtrace_frame_data_t>* frames,
                              BacktraceUnwindError* error) {
  UnwindStackOfflineMap* offline_map = reinterpret_cast<UnwindStackOfflineMap*>(back_map);
  // Create the process memory from the stack data since this will almost
  // always be different each unwind.
  if (!offline_map->CreateProcessMemory(stack)) {
    if (error != nullptr) {
      error->error_code = BACKTRACE_UNWIND_ERROR_SETUP_FAILED;
    }
    return false;
  }
  return Backtrace::Unwind(regs, back_map, frames, 0U, nullptr, error);
}

UnwindStackCurrent::UnwindStackCurrent(pid_t pid, pid_t tid, BacktraceMap* map)
UnwindStackCurrent::UnwindStackCurrent(pid_t pid, pid_t tid, BacktraceMap* map)
    : BacktraceCurrent(pid, tid, map) {}
    : BacktraceCurrent(pid, tid, map) {}


@@ -221,12 +237,12 @@ bool UnwindStackOffline::ReadWord(uint64_t, word_t*) {
Backtrace* Backtrace::CreateOffline(ArchEnum arch, pid_t pid, pid_t tid,
Backtrace* Backtrace::CreateOffline(ArchEnum arch, pid_t pid, pid_t tid,
                                    const std::vector<backtrace_map_t>& maps,
                                    const std::vector<backtrace_map_t>& maps,
                                    const backtrace_stackinfo_t& stack) {
                                    const backtrace_stackinfo_t& stack) {
  BacktraceMap* map = BacktraceMap::CreateOffline(pid, maps, stack);
  std::unique_ptr<UnwindStackOfflineMap> map(
  if (map == nullptr) {
      reinterpret_cast<UnwindStackOfflineMap*>(BacktraceMap::CreateOffline(pid, maps)));
  if (map.get() == nullptr || !map->CreateProcessMemory(stack)) {
    return nullptr;
    return nullptr;
  }
  }

  return new UnwindStackOffline(arch, pid, tid, map.release(), false);
  return new UnwindStackOffline(arch, pid, tid, map, false);
}
}


Backtrace* Backtrace::CreateOffline(ArchEnum arch, pid_t pid, pid_t tid, BacktraceMap* map) {
Backtrace* Backtrace::CreateOffline(ArchEnum arch, pid_t pid, pid_t tid, BacktraceMap* map) {
+10 −10
Original line number Original line Diff line number Diff line
@@ -127,12 +127,7 @@ bool UnwindStackOfflineMap::Build() {
  return false;
  return false;
}
}


bool UnwindStackOfflineMap::Build(const std::vector<backtrace_map_t>& backtrace_maps,
bool UnwindStackOfflineMap::Build(const std::vector<backtrace_map_t>& backtrace_maps) {
                                  const backtrace_stackinfo_t& stack) {
  if (stack.start >= stack.end) {
    return false;
  }

  for (const backtrace_map_t& map : backtrace_maps) {
  for (const backtrace_map_t& map : backtrace_maps) {
    maps_.push_back(map);
    maps_.push_back(map);
  }
  }
@@ -145,6 +140,13 @@ bool UnwindStackOfflineMap::Build(const std::vector<backtrace_map_t>& backtrace_
  for (const backtrace_map_t& map : maps_) {
  for (const backtrace_map_t& map : maps_) {
    maps->Add(map.start, map.end, map.offset, map.flags, map.name, map.load_bias);
    maps->Add(map.start, map.end, map.offset, map.flags, map.name, map.load_bias);
  }
  }
  return true;
}

bool UnwindStackOfflineMap::CreateProcessMemory(const backtrace_stackinfo_t& stack) {
  if (stack.start >= stack.end) {
    return false;
  }


  // Create the process memory from the stack data.
  // Create the process memory from the stack data.
  uint64_t size = stack.end - stack.start;
  uint64_t size = stack.end - stack.start;
@@ -154,7 +156,6 @@ bool UnwindStackOfflineMap::Build(const std::vector<backtrace_map_t>& backtrace_
  std::shared_ptr<unwindstack::Memory> shared_memory(memory);
  std::shared_ptr<unwindstack::Memory> shared_memory(memory);


  process_memory_.reset(new unwindstack::MemoryRange(shared_memory, 0, size, stack.start));
  process_memory_.reset(new unwindstack::MemoryRange(shared_memory, 0, size, stack.start));

  return true;
  return true;
}
}


@@ -182,10 +183,9 @@ BacktraceMap* BacktraceMap::Create(pid_t pid, bool uncached) {
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
// BacktraceMap create offline function.
// BacktraceMap create offline function.
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
BacktraceMap* BacktraceMap::CreateOffline(pid_t pid, const std::vector<backtrace_map_t>& maps,
BacktraceMap* BacktraceMap::CreateOffline(pid_t pid, const std::vector<backtrace_map_t>& maps) {
                                          const backtrace_stackinfo_t& stack) {
  UnwindStackOfflineMap* map = new UnwindStackOfflineMap(pid);
  UnwindStackOfflineMap* map = new UnwindStackOfflineMap(pid);
  if (!map->Build(maps, stack)) {
  if (!map->Build(maps)) {
    delete map;
    delete map;
    return nullptr;
    return nullptr;
  }
  }
+3 −1
Original line number Original line Diff line number Diff line
@@ -76,7 +76,9 @@ class UnwindStackOfflineMap : public UnwindStackMap {


  bool Build() override;
  bool Build() override;


  bool Build(const std::vector<backtrace_map_t>& maps, const backtrace_stackinfo_t& stack);
  bool Build(const std::vector<backtrace_map_t>& maps);

  bool CreateProcessMemory(const backtrace_stackinfo_t& stack);
};
};


#endif  // _LIBBACKTRACE_UNWINDSTACK_MAP_H
#endif  // _LIBBACKTRACE_UNWINDSTACK_MAP_H
+5 −0
Original line number Original line Diff line number Diff line
@@ -151,6 +151,11 @@ class Backtrace {
                     std::vector<backtrace_frame_data_t>* frames, size_t num_ignore_frames,
                     std::vector<backtrace_frame_data_t>* frames, size_t num_ignore_frames,
                     std::vector<std::string>* skip_names, BacktraceUnwindError* error = nullptr);
                     std::vector<std::string>* skip_names, BacktraceUnwindError* error = nullptr);


  static bool UnwindOffline(unwindstack::Regs* regs, BacktraceMap* back_map,
                            const backtrace_stackinfo_t& stack_info,
                            std::vector<backtrace_frame_data_t>* frames,
                            BacktraceUnwindError* error = nullptr);

  // Get the function name and offset into the function given the pc.
  // Get the function name and offset into the function given the pc.
  // If the string is empty, then no valid function name was found,
  // If the string is empty, then no valid function name was found,
  // or the pc is not in any valid map.
  // or the pc is not in any valid map.
+1 −2
Original line number Original line Diff line number Diff line
@@ -64,8 +64,7 @@ public:
  // is unsupported.
  // is unsupported.
  static BacktraceMap* Create(pid_t pid, bool uncached = false);
  static BacktraceMap* Create(pid_t pid, bool uncached = false);


  static BacktraceMap* CreateOffline(pid_t pid, const std::vector<backtrace_map_t>& maps,
  static BacktraceMap* CreateOffline(pid_t pid, const std::vector<backtrace_map_t>& maps);
                                     const backtrace_stackinfo_t& stack);


  virtual ~BacktraceMap();
  virtual ~BacktraceMap();