Skip to content

Commit 2b7c0aa

Browse files
committed
[Linux][Backtracing] Don't try to use process_vm_readv().
We used to try to use `process_vm_readv()` if `CAP_SYS_PTRACE` is enabled. This avoided using signal handlers to catch crashes when we try to read through an invalid pointer, but it complicates the code and it turns out not to work on some Linux kernels where the `process_vm_readv()` syscall is unavailable. rdar://159930644
1 parent 5904da1 commit 2b7c0aa

File tree

1 file changed

+17
-30
lines changed

1 file changed

+17
-30
lines changed

stdlib/public/runtime/CrashHandlerLinux.cpp

Lines changed: 17 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -655,7 +655,6 @@ wait_paused(uint32_t expected, const struct timespec *timeout)
655655
char memserver_stack[4096] __attribute__((aligned(SWIFT_PAGE_SIZE)));
656656
char memserver_buffer[4096];
657657
int memserver_fd;
658-
bool memserver_has_ptrace;
659658
sigjmp_buf memserver_fault_buf;
660659
pid_t memserver_pid;
661660

@@ -712,21 +711,18 @@ memserver_fault(int sig) {
712711

713712
ssize_t __attribute__((noinline))
714713
memserver_read(void *to, const void *from, size_t len) {
715-
if (memserver_has_ptrace) {
716-
// This won't run for older Android APIs anyway, but it can't be compiled
717-
// either, as process_vm_readv() isn't available.
718-
#if !(defined(__ANDROID_API__) && __ANDROID_API__ < 23)
719-
struct iovec local = { to, len };
720-
struct iovec remote = { const_cast<void *>(from), len };
721-
return process_vm_readv(memserver_pid, &local, 1, &remote, 1, 0);
722-
#endif
714+
/* Earlier versions of this code tried to use process_vm_readv() if they
715+
detected that CAP_SYS_PTRACE was enabled. This is theoretically
716+
slightly safer than using signals and memcpy(), but in practice it
717+
turns out that some kernels don't support process_vm_readv() even
718+
when CAP_SYS_PTRACE is enabled.
719+
720+
It seems simpler just to use the signal handlers instead. */
721+
if (!sigsetjmp(memserver_fault_buf, 1)) {
722+
memcpy(to, from, len);
723+
return len;
723724
} else {
724-
if (!sigsetjmp(memserver_fault_buf, 1)) {
725-
memcpy(to, from, len);
726-
return len;
727-
} else {
728-
return -1;
729-
}
725+
return -1;
730726
}
731727
}
732728

@@ -739,21 +735,12 @@ memserver_entry(void *dummy __attribute__((unused))) {
739735
prctl(PR_SET_NAME, "[backtrace]");
740736
#endif
741737

742-
// process_vm_readv() is not available for older Android APIs.
743-
#if defined(__ANDROID_API__) && __ANDROID_API__ < 23
744-
memserver_has_ptrace = false;
745-
#else
746-
memserver_has_ptrace = !!prctl(PR_CAPBSET_READ, CAP_SYS_PTRACE);
747-
#endif
748-
749-
if (!memserver_has_ptrace) {
750-
struct sigaction sa;
751-
sigfillset(&sa.sa_mask);
752-
sa.sa_handler = memserver_fault;
753-
sa.sa_flags = SA_NODEFER;
754-
sigaction(SIGSEGV, &sa, NULL);
755-
sigaction(SIGBUS, &sa, NULL);
756-
}
738+
struct sigaction sa;
739+
sigfillset(&sa.sa_mask);
740+
sa.sa_handler = memserver_fault;
741+
sa.sa_flags = SA_NODEFER;
742+
sigaction(SIGSEGV, &sa, NULL);
743+
sigaction(SIGBUS, &sa, NULL);
757744

758745
for (;;) {
759746
struct memserver_req req;

0 commit comments

Comments
 (0)