1616#endif
1717#include "Python.h"
1818#include <internal/pycore_debug_offsets.h> // _Py_DebugOffsets
19+ #include <internal/pycore_global_objects.h>
1920#include <internal/pycore_frame.h> // FRAME_SUSPENDED_YIELD_FROM
2021#include <internal/pycore_interpframe.h> // FRAME_OWNED_BY_CSTACK
2122#include <internal/pycore_llist.h> // struct llist_node
@@ -804,7 +805,7 @@ static int append_awaited_by(RemoteUnwinderObject *unwinder, unsigned long tid,
804805#define set_exception_cause (unwinder , exc_type , message ) \
805806 do { \
806807 assert(PyErr_Occurred() && "function returned -1 without setting exception"); \
807- if (unwinder->debug && !_Py_RemoteDebug_HasPermissionError ()) { \
808+ if (unwinder->debug && !_Py_RemoteDebug_IsFatalReadError ()) { \
808809 _set_debug_exception_cause(exc_type, message); \
809810 } \
810811 } while (0)
@@ -2264,6 +2265,7 @@ parse_code_object(RemoteUnwinderObject *unwinder,
22642265 PyObject * linetable = NULL ;
22652266 PyObject * lineno = NULL ;
22662267 PyObject * tuple = NULL ;
2268+ int code_metadata_incomplete = 0 ;
22672269
22682270#ifdef Py_GIL_DISABLED
22692271 // In free threading builds, code object addresses might have the low bit set
@@ -2282,29 +2284,59 @@ parse_code_object(RemoteUnwinderObject *unwinder,
22822284 if (_Py_RemoteDebug_PagedReadRemoteMemory (
22832285 & unwinder -> handle , real_address , SIZEOF_CODE_OBJ , code_object ) < 0 )
22842286 {
2285- set_exception_cause (unwinder , PyExc_RuntimeError , "Failed to read code object" );
2286- goto error ;
2287+ if (_Py_RemoteDebug_IsFatalReadError ()) {
2288+ goto error ;
2289+ }
2290+ PyErr_Clear ();
2291+ func = PyUnicode_FromString ("<unreadable frame>" );
2292+ if (!func ) {
2293+ goto error ;
2294+ }
2295+ file = Py_NewRef (_Py_LATIN1_CHR ('~' ));
2296+ goto degraded ;
22872297 }
22882298
22892299 func = read_py_str (unwinder ,
22902300 GET_MEMBER (uintptr_t , code_object , unwinder -> debug_offsets .code_object .qualname ), 1024 );
22912301 if (!func ) {
2292- set_exception_cause (unwinder , PyExc_RuntimeError , "Failed to read function name from code object" );
2293- goto error ;
2302+ if (_Py_RemoteDebug_IsFatalReadError ()) {
2303+ goto error ;
2304+ }
2305+ PyErr_Clear ();
2306+ func = PyUnicode_FromString ("<unknown function>" );
2307+ if (!func ) {
2308+ goto error ;
2309+ }
2310+ code_metadata_incomplete = 1 ;
22942311 }
22952312
22962313 file = read_py_str (unwinder ,
22972314 GET_MEMBER (uintptr_t , code_object , unwinder -> debug_offsets .code_object .filename ), 1024 );
22982315 if (!file ) {
2299- set_exception_cause (unwinder , PyExc_RuntimeError , "Failed to read filename from code object" );
2300- goto error ;
2316+ if (_Py_RemoteDebug_IsFatalReadError ()) {
2317+ goto error ;
2318+ }
2319+ PyErr_Clear ();
2320+ file = PyUnicode_FromString ("<unknown file>" );
2321+ if (!file ) {
2322+ goto error ;
2323+ }
2324+ code_metadata_incomplete = 1 ;
2325+ }
2326+
2327+ if (code_metadata_incomplete ) {
2328+ goto degraded ;
23012329 }
23022330
23032331 linetable = read_py_bytes (unwinder ,
2304- GET_MEMBER (uintptr_t , code_object , unwinder -> debug_offsets .code_object .linetable ), 4096 );
2332+ GET_MEMBER (uintptr_t , code_object , unwinder -> debug_offsets .code_object .linetable ),
2333+ 4096 );
23052334 if (!linetable ) {
2306- set_exception_cause (unwinder , PyExc_RuntimeError , "Failed to read linetable from code object" );
2307- goto error ;
2335+ if (_Py_RemoteDebug_IsFatalReadError ()) {
2336+ goto error ;
2337+ }
2338+ PyErr_Clear ();
2339+ goto degraded ;
23082340 }
23092341
23102342 meta = PyMem_RawMalloc (sizeof (CachedCodeMetadata ));
@@ -2434,6 +2466,19 @@ parse_code_object(RemoteUnwinderObject *unwinder,
24342466 * result = tuple ;
24352467 return 0 ;
24362468
2469+ degraded : {
2470+ RemoteDebuggingState * state = RemoteDebugging_GetStateFromObject ((PyObject * )unwinder );
2471+ PyObject * degraded_tuple = PyStructSequence_New (state -> FrameInfo_Type );
2472+ if (!degraded_tuple ) {
2473+ goto error ;
2474+ }
2475+ PyStructSequence_SetItem (degraded_tuple , 0 , file );
2476+ PyStructSequence_SetItem (degraded_tuple , 1 , Py_NewRef (Py_None ));
2477+ PyStructSequence_SetItem (degraded_tuple , 2 , func );
2478+ * result = degraded_tuple ;
2479+ return 0 ;
2480+ }
2481+
24372482error :
24382483 Py_XDECREF (func );
24392484 Py_XDECREF (file );
0 commit comments