diff --git a/Modules/_testexternalinspection.c b/Modules/_testexternalinspection.c index b43e8b2155730f..b65c5821443ebf 100644 --- a/Modules/_testexternalinspection.c +++ b/Modules/_testexternalinspection.c @@ -45,6 +45,15 @@ struct _Py_AsyncioModuleDebugOffsets { } asyncio_thread_state; }; +// Helper to chain exceptions and avoid repetitions +static void +chain_exceptions(PyObject *exception, const char *string) +{ + PyObject *exc = PyErr_GetRaisedException(); + PyErr_SetString(exception, string); + _PyErr_ChainExceptions1(exc); +} + // Get the PyAsyncioDebug section address for any platform static uintptr_t _Py_RemoteDebug_GetAsyncioDebugAddress(proc_handle_t* handle) @@ -65,7 +74,7 @@ _Py_RemoteDebug_GetAsyncioDebugAddress(proc_handle_t* handle) address = search_map_for_section(handle, "AsyncioDebug", "_asyncio.cpython"); } #else - address = 0; + Py_UNREACHABLE(); #endif return address; @@ -304,7 +313,7 @@ parse_task_name( if ((flags & Py_TPFLAGS_LONG_SUBCLASS)) { long res = read_py_long(handle, offsets, task_name_addr); if (res == -1) { - PyErr_SetString(PyExc_RuntimeError, "Failed to get task name"); + chain_exceptions(PyExc_RuntimeError, "Failed to get task name"); return NULL; } return PyUnicode_FromFormat("Task-%d", res); @@ -482,9 +491,6 @@ parse_task( return -1; } - uintptr_t refcnt; - read_ptr(handle, task_address + sizeof(Py_ssize_t), &refcnt); - PyObject* result = PyList_New(0); if (result == NULL) { return -1; @@ -1159,30 +1165,32 @@ get_all_awaited_by(PyObject* self, PyObject* args) return 0; } + PyObject *result = NULL; + uintptr_t runtime_start_addr = _Py_RemoteDebug_GetPyRuntimeAddress(handle); if (runtime_start_addr == 0) { if (!PyErr_Occurred()) { PyErr_SetString( PyExc_RuntimeError, "Failed to get .PyRuntime address"); } - return NULL; + goto result_err; } struct _Py_DebugOffsets local_debug_offsets; if (_Py_RemoteDebug_ReadDebugOffsets(handle, &runtime_start_addr, &local_debug_offsets)) { - PyErr_SetString(PyExc_RuntimeError, "Failed to read debug offsets"); - return NULL; + chain_exceptions(PyExc_RuntimeError, "Failed to read debug offsets"); + goto result_err; } struct _Py_AsyncioModuleDebugOffsets local_async_debug; if (read_async_debug(handle, &local_async_debug)) { - PyErr_SetString(PyExc_RuntimeError, "Failed to read asyncio debug offsets"); - return NULL; + chain_exceptions(PyExc_RuntimeError, "Failed to read asyncio debug offsets"); + goto result_err; } - PyObject *result = PyList_New(0); + result = PyList_New(0); if (result == NULL) { - return NULL; + goto result_err; } uint64_t interpreter_state_list_head = @@ -1259,7 +1267,7 @@ get_all_awaited_by(PyObject* self, PyObject* args) return result; result_err: - Py_DECREF(result); + Py_XDECREF(result); _Py_RemoteDebug_CleanupProcHandle(handle); return NULL; } @@ -1299,7 +1307,7 @@ get_stack_trace(PyObject* self, PyObject* args) struct _Py_DebugOffsets local_debug_offsets; if (_Py_RemoteDebug_ReadDebugOffsets(handle, &runtime_start_address, &local_debug_offsets)) { - PyErr_SetString(PyExc_RuntimeError, "Failed to read debug offsets"); + chain_exceptions(PyExc_RuntimeError, "Failed to read debug offsets"); goto result_err; } @@ -1357,40 +1365,40 @@ get_async_stack_trace(PyObject* self, PyObject* args) return 0; } + PyObject *result = NULL; + uintptr_t runtime_start_address = _Py_RemoteDebug_GetPyRuntimeAddress(handle); if (runtime_start_address == 0) { if (!PyErr_Occurred()) { PyErr_SetString( PyExc_RuntimeError, "Failed to get .PyRuntime address"); } - return NULL; + goto result_err; } struct _Py_DebugOffsets local_debug_offsets; if (_Py_RemoteDebug_ReadDebugOffsets(handle, &runtime_start_address, &local_debug_offsets)) { - PyErr_SetString(PyExc_RuntimeError, "Failed to read debug offsets"); - return NULL; + chain_exceptions(PyExc_RuntimeError, "Failed to read debug offsets"); + goto result_err; } struct _Py_AsyncioModuleDebugOffsets local_async_debug; if (read_async_debug(handle, &local_async_debug)) { - PyErr_SetString(PyExc_RuntimeError, "Failed to read asyncio debug offsets"); - return NULL; + chain_exceptions(PyExc_RuntimeError, "Failed to read asyncio debug offsets"); + goto result_err; } - PyObject* result = PyList_New(1); + result = PyList_New(1); if (result == NULL) { - return NULL; + goto result_err; } PyObject* calls = PyList_New(0); if (calls == NULL) { - Py_DECREF(result); - return NULL; + goto result_err; } if (PyList_SetItem(result, 0, calls)) { /* steals ref to 'calls' */ - Py_DECREF(result); Py_DECREF(calls); - return NULL; + goto result_err; } uintptr_t running_task_addr = (uintptr_t)NULL; @@ -1398,7 +1406,7 @@ get_async_stack_trace(PyObject* self, PyObject* args) handle, runtime_start_address, &local_debug_offsets, &local_async_debug, &running_task_addr) ) { - PyErr_SetString(PyExc_RuntimeError, "Failed to find running task"); + chain_exceptions(PyExc_RuntimeError, "Failed to find running task"); goto result_err; } @@ -1413,7 +1421,7 @@ get_async_stack_trace(PyObject* self, PyObject* args) running_task_addr + local_async_debug.asyncio_task_object.task_coro, &running_coro_addr )) { - PyErr_SetString(PyExc_RuntimeError, "Failed to read running task coro"); + chain_exceptions(PyExc_RuntimeError, "Failed to read running task coro"); goto result_err; } @@ -1443,7 +1451,7 @@ get_async_stack_trace(PyObject* self, PyObject* args) handle, runtime_start_address, &local_debug_offsets, &address_of_current_frame) ) { - PyErr_SetString(PyExc_RuntimeError, "Failed to find running frame"); + chain_exceptions(PyExc_RuntimeError, "Failed to find running frame"); goto result_err; } @@ -1459,7 +1467,7 @@ get_async_stack_trace(PyObject* self, PyObject* args) ); if (res < 0) { - PyErr_SetString(PyExc_RuntimeError, "Failed to parse async frame object"); + chain_exceptions(PyExc_RuntimeError, "Failed to parse async frame object"); goto result_err; } @@ -1501,7 +1509,7 @@ get_async_stack_trace(PyObject* self, PyObject* args) result_err: _Py_RemoteDebug_CleanupProcHandle(handle); - Py_DECREF(result); + Py_XDECREF(result); return NULL; } diff --git a/Python/remote_debug.h b/Python/remote_debug.h index cb1baf799052d5..edc77c302916ca 100644 --- a/Python/remote_debug.h +++ b/Python/remote_debug.h @@ -342,6 +342,7 @@ search_section_in_file(const char* secname, char* path, uintptr_t base, mach_vm_ munmap(map, fs.st_size); if (close(fd) != 0) { PyErr_SetFromErrno(PyExc_OSError); + result = 0; } return result; } @@ -371,7 +372,9 @@ search_map_for_section(proc_handle_t *handle, const char* secname, const char* s mach_port_t proc_ref = pid_to_task(handle->pid); if (proc_ref == 0) { - PyErr_SetString(PyExc_PermissionError, "Cannot get task for PID"); + if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_PermissionError, "Cannot get task for PID"); + } return 0; } @@ -495,6 +498,7 @@ search_elf_file_for_section( } if (fd >= 0 && close(fd) != 0) { PyErr_SetFromErrno(PyExc_OSError); + result = 0; } return result; } @@ -570,7 +574,10 @@ search_linux_map_for_section(proc_handle_t *handle, const char* secname, const c } PyMem_Free(line); - fclose(maps_file); + if (fclose(maps_file) != 0) { + PyErr_SetFromErrno(PyExc_OSError); + retval = 0; + } return retval; } @@ -681,14 +688,18 @@ _Py_RemoteDebug_GetPyRuntimeAddress(proc_handle_t* handle) address = search_windows_map_for_section(handle, "PyRuntime", L"python"); if (address == 0) { // Error out: 'python' substring covers both executable and DLL + PyObject *exc = PyErr_GetRaisedException(); PyErr_SetString(PyExc_RuntimeError, "Failed to find the PyRuntime section in the process."); + _PyErr_ChainExceptions1(exc); } #elif defined(__linux__) // On Linux, search for 'python' in executable or DLL address = search_linux_map_for_section(handle, "PyRuntime", "python"); if (address == 0) { // Error out: 'python' substring covers both executable and DLL + PyObject *exc = PyErr_GetRaisedException(); PyErr_SetString(PyExc_RuntimeError, "Failed to find the PyRuntime section in the process."); + _PyErr_ChainExceptions1(exc); } #elif defined(__APPLE__) && TARGET_OS_OSX // On macOS, try libpython first, then fall back to python @@ -699,7 +710,7 @@ _Py_RemoteDebug_GetPyRuntimeAddress(proc_handle_t* handle) address = search_map_for_section(handle, "PyRuntime", "python"); } #else - address = 0; + Py_UNREACHABLE(); #endif return address; pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy