Skip to content

_remote_debugging: incorrect error for process_vm_readv() w/ EPERM when detecting the cookie #149619

Description

@maurycy

Bug report

Bug description:

Note Failed to find the PyRuntime section in process 175853 on Linux platform here:

2026-05-09T21:00:48.747402752+0000 ubuntu@f4-metal-medium-lon-1 /home/ubuntu/cpython (main 7241f27) % sudo sysctl -w kernel.yama.ptrace_scope=1
kernel.yama.ptrace_scope = 1
2026-05-09T21:00:49.153189782+0000 ubuntu@f4-metal-medium-lon-1 /home/ubuntu/cpython (main 7241f27) % ./python -c "import time; time.sleep(60)"&
[1] 175853
2026-05-09T21:00:51.504230609+0000 ubuntu@f4-metal-medium-lon-1 /home/ubuntu/cpython (main 7241f27) % ./python -m profiling.sampling attach $!
Failed to find the PyRuntime section in process 175853 on Linux platform
[1] 2026-05-09T21:00:54.515838389+0000 ubuntu@f4-metal-medium-lon-1 /home/ubuntu/cpython (main 7241f27) % sudo sysctl -w kernel.yama.ptrace_scope=0
kernel.yama.ptrace_scope = 0
2026-05-09T21:00:57.313995182+0000 ubuntu@f4-metal-medium-lon-1 /home/ubuntu/cpython (main 7241f27) % ./python -c "import time; time.sleep(60)"&
[2] 175951
2026-05-09T21:00:59.679641859+0000 ubuntu@f4-metal-medium-lon-1 /home/ubuntu/cpython (main 7241f27) % ./python -m profiling.sampling attach $!
[1] - done ./python -c "import time; time.sleep(60)"
Captured 57,731 samples in 57.73 seconds
Sample rate: 1,000.00 samples/sec
Error rate: 0.00
[2] + done ./python -c "import time; time.sleep(60)"
Profile Stats:
nsamples sample% tottime (s) cumul% cumtime (s) filename:lineno(function)
57729/57729 100.0 57.729 100.0 57.729 <string>:1(<module>)
Legend:
nsamples: Direct/Cumulative samples (direct executing / on call stack)
sample%: Percentage of total samples this functionwas directly executing
tottime: Estimated total time spent directly in this function
cumul%: Percentage of total samples when this functionwas on the call stack
cumtime: Estimated cumulative time (including timein called functions)
filename:lineno(function): Function location and name
Summary of Interesting Functions:
Functions with Highest Direct/Cumulative Ratio (Hot Spots):
1.000 direct/cumulative ratio, 100.0% direct samples: <string>:(<module>)
Functions with Highest Call Frequency (Indirect Calls):
Functions with Highest Call Magnification (Cumulative/Direct):
2026-05-09T21:01:59.697134414+0000 ubuntu@f4-metal-medium-lon-1 /home/ubuntu/cpython (main 7241f27) % 

The wrapper handles PermissionError well:

if__name__=='__main__':
try:
main()
exceptPermissionError:
handle_permission_error()

defhandle_permission_error():
"""Handle PermissionError by displaying appropriate error message."""
ifsys.platform=="darwin":
print(MACOS_PERMISSION_ERROR, file=sys.stderr)
elifsys.platform.startswith("linux"):
print(LINUX_PERMISSION_ERROR, file=sys.stderr)
elifsys.platform.startswith("win"):
print(WINDOWS_PERMISSION_ERROR, file=sys.stderr)
else:
print(GENERIC_PERMISSION_ERROR, file=sys.stderr)
sys.exit(1)

LINUX_PERMISSION_ERROR="""
🔒 Tachyon was unable to access process memory. This could be because tachyon
has insufficient privileges (the required capability is CAP_SYS_PTRACE).
Unprivileged processes cannot trace processes that they cannot send signals
to or those running set-user-ID/set-group-ID programs, for security reasons.
If your uid matches the uid of the target process you want to analyze, you
can do one of the following to get 'ptrace' scope permissions:
* If you are running inside a Docker container, you need to make sure you
start the container using the '--cap-add=SYS_PTRACE' or '--privileged'
command line arguments. Notice that this may not be enough if you are not
running as 'root' inside the Docker container as you may need to disable
hardening (see next points).
* Try running again with elevated permissions by running 'sudo -E !!'.
* You can disable kernel hardening for the current session temporarily (until
a reboot happens) by running 'echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope'.
"""

but it's swallowed as RuntimeError:

#elif defined(__linux__) &&HAVE_PROCESS_VM_READV
// On Linux, search for 'python' in executable or DLL
address=search_linux_map_for_section(handle, "PyRuntime", "python",
_Py_RemoteDebug_ValidatePyRuntimeCookie);
if (address==0) {
// Error out: 'python' substring covers both executable and DLL
PyObject*exc=PyErr_GetRaisedException();
PyErr_Format(PyExc_RuntimeError,
"Failed to find the PyRuntime section in process %d on Linux platform",
handle->pid);
_PyErr_ChainExceptions1(exc);
}

The error bubbles out of

staticint
_Py_RemoteDebug_ValidatePyRuntimeCookie(proc_handle_t*handle, uintptr_taddress)
{
if (address==0) {
return0;
}
charbuf[sizeof(_Py_Debug_Cookie) -1];
if (_Py_RemoteDebug_ReadRemoteMemory(handle, address, sizeof(buf), buf) !=0) {
PyErr_Clear();
return0;
}
returnmemcmp(buf, _Py_Debug_Cookie, sizeof(buf)) ==0;
}

hence such a cookie panic

CPython versions tested on:

CPython main branch

Operating systems tested on:

Linux

Linked PRs

Metadata

Metadata

Labels

interpreter-core(Objects, Python, Grammar, and Parser dirs)topic-profilingtype-bugAn unexpected behavior, bug, or error

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions