[libunwind] [libunwind] Replace process_vm_readv with pipe (PR #74791)
Fangrui Song via cfe-commits
cfe-commits at lists.llvm.org
Thu Dec 7 17:09:24 PST 2023
================
@@ -2700,19 +2701,18 @@ bool UnwindCursor<A, R>::setInfoForSigReturn(Registers_arm64 &) {
// [1] https://github.com/torvalds/linux/blob/master/arch/arm64/kernel/vdso/sigreturn.S
const pint_t pc = static_cast<pint_t>(this->getReg(UNW_REG_IP));
// The PC might contain an invalid address if the unwind info is bad, so
- // directly accessing it could cause a segfault. Use process_vm_readv to read
- // the memory safely instead. process_vm_readv was added in Linux 3.2, and
- // AArch64 supported was added in Linux 3.7, so the syscall is guaranteed to
- // be present. Unfortunately, there are Linux AArch64 environments where the
- // libc wrapper for the syscall might not be present (e.g. Android 5), so call
- // the syscall directly instead.
+ // directly accessing it could cause a segfault. Use pipe/write/read to read
+ // the memory safely instead.
+ int pipefd[2];
+ if (pipe2(pipefd, O_CLOEXEC | O_NONBLOCK) == -1)
+ return false;
uint32_t instructions[2];
- struct iovec local_iov = {&instructions, sizeof instructions};
- struct iovec remote_iov = {reinterpret_cast<void *>(pc), sizeof instructions};
- long bytesRead =
- syscall(SYS_process_vm_readv, getpid(), &local_iov, 1, &remote_iov, 1, 0);
+ const auto bufferSize = sizeof instructions;
+ if (write(pipefd[1], reinterpret_cast<void *>(pc), bufferSize) != bufferSize)
+ return false;
+ const auto bytesRead = read(pipefd[0], instructions, bufferSize);
----------------
MaskRay wrote:
Consider SYS_rt_sigprocmask like absl/debugging/internal/address_is_readable.cc
https://github.com/llvm/llvm-project/pull/74791
More information about the cfe-commits
mailing list