[clang] [llvm] [libunwind] [clang-tools-extra] [libunwind] Replace process_vm_readv with SYS_rt_sigprocmask (PR #74791)
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Wed Dec 20 13:09:31 PST 2023
================
@@ -2974,6 +2966,37 @@ bool UnwindCursor<A, R>::getFunctionName(char *buf, size_t bufLen,
buf, bufLen, offset);
}
+#if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN)
+template <typename A, typename R>
+bool UnwindCursor<A, R>::isReadableAddr(const pint_t addr) const {
+ // This code is heavily based on Abseil's 'address_is_readable.cc',
+ // which is Copyright Abseil Authors (2017).
+
+ const auto sigsetAddr = reinterpret_cast<sigset_t *>(addr);
+ // We have to check that addr is nullptr because sigprocmask allows that
+ // as an argument without failure.
+ if (!sigsetAddr)
+ return false;
+ // We MUST use a raw syscall here, as wrappers may try to access
+ // sigsetAddr which may cause a SIGSEGV. A raw syscall however is
+ // safe. Additionally, we need to pass the kernel_sigset_size, which is
+ // different from libc sizeof(sigset_t). For the majority of architectures,
+ // it's 64 bits (_NSIG), and libc NSIG is _NSIG + 1.
+ const auto kernelSigsetSize = NSIG / 8;
+ const int Result = syscall(SYS_rt_sigprocmask, /*how=*/~0, sigsetAddr,
+ nullptr, kernelSigsetSize);
+ (void)Result;
+ // Because our "how" is invalid, this syscall should always fail, and our
+ // errno should always be EINVAL or an EFAULT. EFAULT is not guaranteed
+ // by the POSIX standard. Additionally, this relies on the Linux kernel
----------------
MaskRay wrote:
"EFAULT is not guaranteed by the POSIX standard." should be removed since the whole function is Linux specific
https://github.com/llvm/llvm-project/pull/74791
More information about the llvm-commits
mailing list