Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix crash in ``_remote_debugging`` that caused ``test_external_inspection`` to intermittently fail. Patch by Taegyun Kim.
25 changes: 20 additions & 5 deletions Modules/_remote_debugging/_remote_debugging.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ extern "C" {
#include "internal/pycore_interpframe.h" // FRAME_OWNED_BY_INTERPRETER
#include "internal/pycore_llist.h" // struct llist_node
#include "internal/pycore_long.h" // _PyLong_GetZero
#include "internal/pycore_pyerrors.h" // _PyErr_FormatFromCause
#include "internal/pycore_stackref.h" // Py_TAG_BITS
#include "../../Python/remote_debug.h"

Expand Down Expand Up @@ -172,11 +173,25 @@ typedef enum _WIN32_THREADSTATE {
#define THREAD_STATUS_GIL_REQUESTED (1 << 3)
#define THREAD_STATUS_HAS_EXCEPTION (1 << 4)

/* Exception cause macro */
#define set_exception_cause(unwinder, exc_type, message) \
if (unwinder->debug) { \
_set_debug_exception_cause(exc_type, message); \
}
/* Exception cause macro - chains context to existing exceptions in debug mode.
Comment thread
taegyunkim marked this conversation as resolved.
Outdated
* This macro assumes an exception has already been set by the failing function.
* If no exception exists, this indicates a bug that should be fixed. */
#define set_exception_cause(unwinder, exc_type, message) \
do { \
if (!PyErr_ExceptionMatches(PyExc_PermissionError)) { \
if (PyErr_Occurred()) { \
if (unwinder->debug) { \
/* Chain exception with context */ \
_PyErr_FormatFromCause(exc_type, "%s", message); \
} \
} else { \
/* BUG: Exception should have been set by caller */ \
/* Fallback prevents crash; assert catches bug in debug builds */ \
PyErr_SetString(exc_type, message); \
assert(PyErr_Occurred() && "function returned -1 without setting exception"); \
} \
} \
} while (0)

/* ============================================================================
* TYPE DEFINITIONS
Expand Down
3 changes: 2 additions & 1 deletion Python/remote_debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -1263,6 +1263,7 @@ _Py_RemoteDebug_PagedReadRemoteMemory(proc_handle_t *handle,
if (entry->data == NULL) {
entry->data = PyMem_RawMalloc(page_size);
if (entry->data == NULL) {
PyErr_NoMemory();
_set_debug_exception_cause(PyExc_MemoryError,
"Cannot allocate %zu bytes for page cache entry "
"during read from PID %d at address 0x%lx",
Expand All @@ -1272,7 +1273,7 @@ _Py_RemoteDebug_PagedReadRemoteMemory(proc_handle_t *handle,
}

if (_Py_RemoteDebug_ReadRemoteMemory(handle, page_base, page_size, entry->data) < 0) {
// Try to just copy the exact ammount as a fallback
// Try to just copy the exact amount as a fallback
PyErr_Clear();
goto fallback;
}
Expand Down
Loading