| /****************************************************************************** | |
| * Remote Debugging Module - Interpreters Functions | |
| * | |
| * This file contains function for iterating interpreters. | |
| ******************************************************************************/ | |
| #include "_remote_debugging.h" | |
| int | |
| iterate_interpreters( | |
| RuntimeOffsets *offsets, | |
| interpreter_processor_func processor, | |
| void *context | |
| ) { | |
| uintptr_t interpreters_head_addr = | |
| offsets->runtime_start_address | |
| + (uintptr_t)offsets->debug_offsets.runtime_state.interpreters_head; | |
| uintptr_t interpreter_id_offset = | |
| (uintptr_t)offsets->debug_offsets.interpreter_state.id; | |
| uintptr_t interpreter_next_offset = | |
| (uintptr_t)offsets->debug_offsets.interpreter_state.next; | |
| uintptr_t interpreter_state_addr; | |
| if (_Py_RemoteDebug_ReadRemoteMemory(&offsets->handle, | |
| interpreters_head_addr, | |
| sizeof(void*), | |
| &interpreter_state_addr) < 0) { | |
| set_exception_cause(offsets, PyExc_RuntimeError, "Failed to read interpreter state address"); | |
| return -1; | |
| } | |
| if (interpreter_state_addr == 0) { | |
| PyErr_SetString(PyExc_RuntimeError, "No interpreter state found"); | |
| return -1; | |
| } | |
| int64_t iid = 0; | |
| static_assert( | |
| sizeof((((PyInterpreterState*)NULL)->id)) == sizeof(iid), | |
| "Sizeof of PyInterpreterState.id mismatch with local iid value"); | |
| while (interpreter_state_addr != 0) { | |
| if (_Py_RemoteDebug_ReadRemoteMemory( | |
| &offsets->handle, | |
| interpreter_state_addr + interpreter_id_offset, | |
| sizeof(iid), | |
| &iid) < 0) { | |
| set_exception_cause(offsets, PyExc_RuntimeError, "Failed to read interpreter id"); | |
| return -1; | |
| } | |
| if (processor(offsets, interpreter_state_addr, iid, context) < 0) { | |
| return -1; | |
| } | |
| if (_Py_RemoteDebug_ReadRemoteMemory( | |
| &offsets->handle, | |
| interpreter_state_addr + interpreter_next_offset, | |
| sizeof(void*), | |
| &interpreter_state_addr) < 0) { | |
| set_exception_cause(offsets, PyExc_RuntimeError, "Failed to read next interpreter state"); | |
| return -1; | |
| } | |
| } | |
| return 0; | |
| } |