mirror of
https://github.com/python/cpython.git
synced 2026-02-21 22:50:55 +00:00
gh-144563: Fix remote debugging with duplicate libpython mappings from ctypes (#144595)
When _ctypes is imported, it may call dlopen on the libpython shared library, causing the dynamic linker to load a second mapping of the library into the process address space. The remote debugging code iterates memory regions from low addresses upward and returns the first mapping whose filename matches libpython. After _ctypes is imported, it finds the dlopen'd copy first, but that copy's PyRuntime section was never initialized, so reading debug offsets from it fails. Fix this by validating each candidate PyRuntime address before accepting it. The validation reads the first 8 bytes and checks for the "xdebugpy" cookie that is only present in an initialized PyRuntime. Uninitialized duplicate mappings will fail this check and be skipped, allowing the search to continue to the real, initialized PyRuntime.
This commit is contained in:
parent
d2d245942e
commit
2c1ca6bb5b
4 changed files with 99 additions and 14 deletions
|
|
@ -18,7 +18,8 @@ _Py_RemoteDebug_GetAsyncioDebugAddress(proc_handle_t* handle)
|
|||
|
||||
#ifdef MS_WINDOWS
|
||||
// On Windows, search for asyncio debug in executable or DLL
|
||||
address = search_windows_map_for_section(handle, "AsyncioD", L"_asyncio");
|
||||
address = search_windows_map_for_section(handle, "AsyncioD", L"_asyncio",
|
||||
NULL);
|
||||
if (address == 0) {
|
||||
// Error out: 'python' substring covers both executable and DLL
|
||||
PyObject *exc = PyErr_GetRaisedException();
|
||||
|
|
@ -27,7 +28,8 @@ _Py_RemoteDebug_GetAsyncioDebugAddress(proc_handle_t* handle)
|
|||
}
|
||||
#elif defined(__linux__) && HAVE_PROCESS_VM_READV
|
||||
// On Linux, search for asyncio debug in executable or DLL
|
||||
address = search_linux_map_for_section(handle, "AsyncioDebug", "python");
|
||||
address = search_linux_map_for_section(handle, "AsyncioDebug", "python",
|
||||
NULL);
|
||||
if (address == 0) {
|
||||
// Error out: 'python' substring covers both executable and DLL
|
||||
PyObject *exc = PyErr_GetRaisedException();
|
||||
|
|
@ -36,10 +38,12 @@ _Py_RemoteDebug_GetAsyncioDebugAddress(proc_handle_t* handle)
|
|||
}
|
||||
#elif defined(__APPLE__) && TARGET_OS_OSX
|
||||
// On macOS, try libpython first, then fall back to python
|
||||
address = search_map_for_section(handle, "AsyncioDebug", "libpython");
|
||||
address = search_map_for_section(handle, "AsyncioDebug", "libpython",
|
||||
NULL);
|
||||
if (address == 0) {
|
||||
PyErr_Clear();
|
||||
address = search_map_for_section(handle, "AsyncioDebug", "python");
|
||||
address = search_map_for_section(handle, "AsyncioDebug", "python",
|
||||
NULL);
|
||||
}
|
||||
if (address == 0) {
|
||||
// Error out: 'python' substring covers both executable and DLL
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue