Skip to content

Commit

Permalink
Chore: update from upstream (#6)
Browse files Browse the repository at this point in the history
synced with commit:

235e2604e2fa3c1f8f7a68c5e285f9622e741e64

of upstream repo:

https://android.googlesource.com/platform/system/unwinding
  • Loading branch information
supervacuus authored Oct 6, 2022
1 parent 90d80b7 commit 5a3cf38
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 6 deletions.
2 changes: 0 additions & 2 deletions Elf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,6 @@
#include <unwindstack/Regs.h>
#include <unwindstack/SharedString.h>

#include <android-base/stringprintf.h>

#include "ElfInterfaceArm.h"
#include "Symbols.h"

Expand Down
23 changes: 21 additions & 2 deletions Regs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <vector>

#include <unwindstack/Elf.h>
#include <unwindstack/Log.h>
#include <unwindstack/MapInfo.h>
#include <unwindstack/Regs.h>
#include <unwindstack/RegsArm.h>
Expand All @@ -42,14 +43,18 @@ static constexpr size_t kMaxUserRegsSize = std::max(

// This function assumes that reg_data is already aligned to a 64 bit value.
// If not this could crash with an unaligned access.
Regs* Regs::RemoteGet(pid_t pid) {
Regs* Regs::RemoteGet(pid_t pid, ErrorCode* error_code) {
// Make the buffer large enough to contain the largest registers type.
std::vector<uint64_t> buffer(kMaxUserRegsSize / sizeof(uint64_t));
struct iovec io;
io.iov_base = buffer.data();
io.iov_len = buffer.size() * sizeof(uint64_t);

if (ptrace(PTRACE_GETREGSET, pid, NT_PRSTATUS, reinterpret_cast<void*>(&io)) == -1) {
Log::Error("PTRACE_GETREGSET failed for pid %d: %s", pid, strerror(errno));
if (error_code != nullptr) {
*error_code = ERROR_PTRACE_CALL;
}
return nullptr;
}

Expand All @@ -64,17 +69,26 @@ Regs* Regs::RemoteGet(pid_t pid) {
case sizeof(arm64_user_regs):
return RegsArm64::Read(buffer.data());
}

Log::Error("No matching size of user regs structure for pid %d: size %zu", pid, io.iov_len);
if (error_code != nullptr) {
*error_code = ERROR_UNSUPPORTED;
}
return nullptr;
}

ArchEnum Regs::RemoteGetArch(pid_t pid) {
ArchEnum Regs::RemoteGetArch(pid_t pid, ErrorCode* error_code) {
// Make the buffer large enough to contain the largest registers type.
std::vector<uint64_t> buffer(kMaxUserRegsSize / sizeof(uint64_t));
struct iovec io;
io.iov_base = buffer.data();
io.iov_len = buffer.size() * sizeof(uint64_t);

if (ptrace(PTRACE_GETREGSET, pid, NT_PRSTATUS, reinterpret_cast<void*>(&io)) == -1) {
Log::Error("PTRACE_GETREGSET failed for pid %d: %s", pid, strerror(errno));
if (error_code != nullptr) {
*error_code = ERROR_PTRACE_CALL;
}
return ARCH_UNKNOWN;
}

Expand All @@ -89,6 +103,11 @@ ArchEnum Regs::RemoteGetArch(pid_t pid) {
case sizeof(arm64_user_regs):
return ARCH_ARM64;
}

Log::Error("No matching size of user regs structure for pid %d: size %zu", pid, io.iov_len);
if (error_code != nullptr) {
*error_code = ERROR_UNSUPPORTED;
}
return ARCH_UNKNOWN;
}

Expand Down
3 changes: 3 additions & 0 deletions include/unwindstack/Error.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ enum ErrorCode : uint8_t {
ERROR_BAD_ARCH, // Arch invalid (none, or mismatched).
ERROR_MAPS_PARSE, // Failed to parse maps data.
ERROR_INVALID_PARAMETER, // Invalid parameter passed to function.
ERROR_PTRACE_CALL, // Ptrace call failed while unwinding.
ERROR_MAX = ERROR_INVALID_PARAMETER,
};

Expand Down Expand Up @@ -76,6 +77,8 @@ static inline const char* GetErrorCodeString(ErrorCode error) {
return "Failed to parse maps";
case ERROR_INVALID_PARAMETER:
return "Invalid parameter";
case ERROR_PTRACE_CALL:
return "Ptrace Call Failed";
}
}

Expand Down
5 changes: 3 additions & 2 deletions include/unwindstack/Regs.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <vector>

#include <unwindstack/Arch.h>
#include <unwindstack/Error.h>

namespace unwindstack {

Expand Down Expand Up @@ -81,8 +82,8 @@ class Regs {
virtual Regs* Clone() = 0;

static ArchEnum CurrentArch();
static ArchEnum RemoteGetArch(pid_t pid);
static Regs* RemoteGet(pid_t pid);
static ArchEnum RemoteGetArch(pid_t pid, ErrorCode* error_code = nullptr);
static Regs* RemoteGet(pid_t pid, ErrorCode* error_code = nullptr);
static Regs* CreateFromUcontext(ArchEnum arch, void* ucontext);
static Regs* CreateFromLocal();

Expand Down

0 comments on commit 5a3cf38

Please sign in to comment.