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

Commit 23040c25 authored by Christopher Ferris's avatar Christopher Ferris Committed by android-build-merger
Browse files

Merge "Add support for UnwinderFromPid object." am: b94c2e52 am: 27d7e2a3

am: 4664997f

Change-Id: I5f7bcce995a6658b7bdbec8088da86298d19078b
parents 2453c029 4664997f
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -127,6 +127,10 @@ cc_library {
        },
    },

    whole_static_libs: [
        "libdemangle"
    ],

    static_libs: [
        "libprocinfo",
    ],
@@ -189,6 +193,7 @@ cc_test {
        "tests/MapInfoCreateMemoryTest.cpp",
        "tests/MapInfoGetElfTest.cpp",
        "tests/MapInfoGetLoadBiasTest.cpp",
        "tests/MapInfoTest.cpp",
        "tests/MapsTest.cpp",
        "tests/MemoryBufferTest.cpp",
        "tests/MemoryCacheTest.cpp",
+13 −0
Original line number Diff line number Diff line
@@ -221,6 +221,19 @@ Elf* MapInfo::GetElf(const std::shared_ptr<Memory>& process_memory, ArchEnum exp
  return elf.get();
}

bool MapInfo::GetFunctionName(uint64_t addr, std::string* name, uint64_t* func_offset) {
  {
    // Make sure no other thread is trying to update this elf object.
    std::lock_guard<std::mutex> guard(mutex_);
    if (elf == nullptr) {
      return false;
    }
  }
  // No longer need the lock, once the elf object is created, it is not deleted
  // until this object is deleted.
  return elf->GetFunctionName(addr, name, func_offset);
}

uint64_t MapInfo::GetLoadBias(const std::shared_ptr<Memory>& process_memory) {
  uint64_t cur_load_bias = load_bias.load();
  if (cur_load_bias != static_cast<uint64_t>(-1)) {
+29 −1
Original line number Diff line number Diff line
@@ -26,10 +26,13 @@

#include <android-base/stringprintf.h>

#include <demangle.h>

#include <unwindstack/Elf.h>
#include <unwindstack/JitDebug.h>
#include <unwindstack/MapInfo.h>
#include <unwindstack/Maps.h>
#include <unwindstack/Memory.h>
#include <unwindstack/Unwinder.h>

#if !defined(NO_LIBDEXFILE_SUPPORT)
@@ -306,7 +309,7 @@ std::string Unwinder::FormatFrame(const FrameData& frame, bool is32bit) {
  }

  if (!frame.function_name.empty()) {
    data += " (" + frame.function_name;
    data += " (" + demangle(frame.function_name.c_str());
    if (frame.function_offset != 0) {
      data += android::base::StringPrintf("+%" PRId64, frame.function_offset);
    }
@@ -327,4 +330,29 @@ void Unwinder::SetDexFiles(DexFiles* dex_files, ArchEnum arch) {
}
#endif

bool UnwinderFromPid::Init(ArchEnum arch) {
  if (pid_ == getpid()) {
    maps_ptr_.reset(new LocalMaps());
  } else {
    maps_ptr_.reset(new RemoteMaps(pid_));
  }
  if (!maps_ptr_->Parse()) {
    return false;
  }
  maps_ = maps_ptr_.get();

  process_memory_ = Memory::CreateProcessMemoryCached(pid_);

  jit_debug_ptr_.reset(new JitDebug(process_memory_));
  jit_debug_ = jit_debug_ptr_.get();
  SetJitDebug(jit_debug_, arch);
#if !defined(NO_LIBDEXFILE_SUPPORT)
  dex_files_ptr_.reset(new DexFiles(process_memory_));
  dex_files_ = dex_files_ptr_.get();
  SetDexFiles(dex_files_, arch);
#endif

  return true;
}

}  // namespace unwindstack
+2 −0
Original line number Diff line number Diff line
@@ -75,6 +75,8 @@ struct MapInfo {

  Memory* CreateMemory(const std::shared_ptr<Memory>& process_memory);

  bool GetFunctionName(uint64_t addr, std::string* name, uint64_t* func_offset);

 private:
  MapInfo(const MapInfo&) = delete;
  void operator=(const MapInfo&) = delete;
+30 −3
Original line number Diff line number Diff line
@@ -24,7 +24,9 @@
#include <string>
#include <vector>

#include <unwindstack/DexFiles.h>
#include <unwindstack/Error.h>
#include <unwindstack/JitDebug.h>
#include <unwindstack/Maps.h>
#include <unwindstack/Memory.h>
#include <unwindstack/Regs.h>
@@ -32,9 +34,7 @@
namespace unwindstack {

// Forward declarations.
class DexFiles;
class Elf;
class JitDebug;
enum ArchEnum : uint8_t;

struct FrameData {
@@ -67,6 +67,11 @@ class Unwinder {
      : max_frames_(max_frames), maps_(maps), regs_(regs), process_memory_(process_memory) {
    frames_.reserve(max_frames);
  }
  Unwinder(size_t max_frames, Maps* maps, std::shared_ptr<Memory> process_memory)
      : max_frames_(max_frames), maps_(maps), process_memory_(process_memory) {
    frames_.reserve(max_frames);
  }

  ~Unwinder() = default;

  void Unwind(const std::vector<std::string>* initial_map_names_to_skip = nullptr,
@@ -81,6 +86,10 @@ class Unwinder {

  void SetJitDebug(JitDebug* jit_debug, ArchEnum arch);

  void SetRegs(Regs* regs) { regs_ = regs; }
  Maps* GetMaps() { return maps_; }
  std::shared_ptr<Memory>& GetProcessMemory() { return process_memory_; }

  // 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; }
@@ -92,7 +101,9 @@ class Unwinder {
  ErrorCode LastErrorCode() { return last_error_.code; }
  uint64_t LastErrorAddress() { return last_error_.address; }

 private:
 protected:
  Unwinder(size_t max_frames) : max_frames_(max_frames) { frames_.reserve(max_frames); }

  void FillInDexFrame();
  void FillInFrame(MapInfo* map_info, Elf* elf, uint64_t rel_pc, uint64_t func_pc,
                   uint64_t pc_adjustment);
@@ -110,6 +121,22 @@ class Unwinder {
  ErrorData last_error_;
};

class UnwinderFromPid : public Unwinder {
 public:
  UnwinderFromPid(size_t max_frames, pid_t pid) : Unwinder(max_frames), pid_(pid) {}
  ~UnwinderFromPid() = default;

  bool Init(ArchEnum arch);

 private:
  pid_t pid_;
  std::unique_ptr<Maps> maps_ptr_;
  std::unique_ptr<JitDebug> jit_debug_ptr_;
#if !defined(NO_LIBDEXFILE_SUPPORT)
  std::unique_ptr<DexFiles> dex_files_ptr_;
#endif
};

}  // namespace unwindstack

#endif  // _LIBUNWINDSTACK_UNWINDER_H
Loading