-
-
Notifications
You must be signed in to change notification settings - Fork 32.1k
gh-134876: Add fallback for when process_vm_readv fails with ENOSYS #134878
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool. If this change has little impact on Python users, wait for a maintainer to apply the |
I think the those tests are only failing because compilation fails on gcc-10. I'll have a look and see if I can obtain a copy and will update accordingly. |
938b91c
to
90b08e6
Compare
Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool. If this change has little impact on Python users, wait for a maintainer to apply the |
Python/remote_debug.h
Outdated
@@ -952,6 +955,38 @@ _Py_RemoteDebug_ReadRemoteMemory(proc_handle_t *handle, uintptr_t remote_address | |||
result += read_bytes; | |||
} while ((size_t)read_bytes != local[0].iov_len); | |||
return 0; | |||
fallback: | |||
; // statement after label needed by gcc 10 and earlier |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you factor the fallback out into a different function. I think this makes the normal path more difficult to read
Python/remote_debug.h
Outdated
char mem_file_path[64]; | ||
off_t offset = 0; | ||
sprintf(mem_file_path, "/proc/%d/mem", handle->pid); | ||
int fd = open(mem_file_path, O_RDONLY); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is going to be tremendously inefficient for a profiler because it keeps opening the pseudo file all the time
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could add the file descriptor to proc_handle_t
with an initial value of -1 and then open only on the first ENOSYS
. Any thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can guard it with macros for process_vm_readv but we are already checking for they to compile all of this in so you still need to deal with that problem
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah no my bad. The problem here is that the function IS defined but the kernel refuses.... alright in that case yeah add it with a guard for only Linux
Python/remote_debug.h
Outdated
|
||
result += read_bytes; | ||
} while ((size_t)read_bytes != local[0].iov_len); | ||
close(fd); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as before
Python/remote_debug.h
Outdated
local[0].iov_len = len - result; | ||
offset = remote_address + result; | ||
|
||
read_bytes = preadv(fd, local, 1, offset); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You need to check for preadv and gate it by a macro as this is not available in all platforms IIRC
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I gave this a go, but I think it's making the code a lot more complicated.
I now took a look at the histories of glibc and musl.
In musl, both both preadv
and process_vm_readv
were added in 2012 (searches: preadv, process_vm_readv)
In glibc preadv
was added in glibc 2.10 and process_vm_readv
in glibc 2.15 (man pages: preadv, process_vm_readv). Those were released in 2009 and 2012 respectively. So process_vm_readv
is good enough as a guard here.
Seems Android is the one you are thinking of, https://android.googlesource.com/platform/bionic/+/refs/heads/main/libc/include/sys/uio.h
It states preadv
is available at API level 24 and process_vm_readv
at API level 23, which are from Android 7 (2016) and Android 6 (2015) respectively. I wasn't able to find somewhere stating which versions we support.
I think I will switch to pread
and pwrite
which have been available a lot longer. I tried to do that but I was forever unhappy with the name for the loop-inner count/len variable. I tried to_read
, count
, len_remaining
, bytes_remaining
, ... I think I will come back to this tomorrow.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
preadv
is available at API level 24 andprocess_vm_readv
at API level 23, which are from Android 7 (2016) and Android 6 (2015) respectively. I wasn't able to find somewhere stating which versions we support.
This is defined in Android/android-env.sh. Python 3.13 requires API level 21 or greater, and Python 3.14 increases that to 24.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given, this, I think is fine, just drop a comment so we know why are we not gating it :)
Python/remote_debugging.c
Outdated
result += written; | ||
} while ((size_t)written != local[0].iov_len); | ||
return 0; | ||
fallback: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same feedback as the read path
A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated. Once you have made the requested changes, please leave a comment on this pull request containing the phrase |
90b08e6
to
cbea7a2
Compare
Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool. If this change has little impact on Python users, wait for a maintainer to apply the |
cbea7a2
to
5fd8ff6
Compare
Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool. If this change has little impact on Python users, wait for a maintainer to apply the |
5fd8ff6
to
ef8ae45
Compare
Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool. If this change has little impact on Python users, wait for a maintainer to apply the |
ef8ae45
to
f1eb6c0
Compare
Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool. If this change has little impact on Python users, wait for a maintainer to apply the |
@cakemanny one small comment: we squash merge so there is no need to rebase. It's easier to review if you just add commits on top so we don't need to review the full thing every iteration :) |
I have made the requested changes; please review again |
Thanks for making the requested changes! @pablogsal: please review the changes made to this pull request. |
This adds a fallback
/proc/[pid]/mem
from theproc(5)
filesystem whenprocess_vm_readv
andprocess_vm_writev
are not compiled into the kernel.Regarding tests, these are covered by
./python -m test --match 'test_remote_pdb'
, but only on affected systems.Do say if this merits a NEWS entry, I wasn't sure because it's a fix for not yet released python versions.