@@ -45,6 +45,15 @@ struct _Py_AsyncioModuleDebugOffsets {
4545 } asyncio_thread_state ;
4646};
4747
48+ // Helper to chain exceptions and avoid repetitions
49+ static void
50+ chain_exceptions (PyObject * exception , const char * string )
51+ {
52+ PyObject * exc = PyErr_GetRaisedException ();
53+ PyErr_SetString (exception , string );
54+ _PyErr_ChainExceptions1 (exc );
55+ }
56+
4857// Get the PyAsyncioDebug section address for any platform
4958static uintptr_t
5059_Py_RemoteDebug_GetAsyncioDebugAddress (proc_handle_t * handle )
@@ -65,7 +74,7 @@ _Py_RemoteDebug_GetAsyncioDebugAddress(proc_handle_t* handle)
6574 address = search_map_for_section (handle , "AsyncioDebug" , "_asyncio.cpython" );
6675 }
6776#else
68- address = 0 ;
77+ Py_UNREACHABLE () ;
6978#endif
7079
7180 return address ;
@@ -304,7 +313,7 @@ parse_task_name(
304313 if ((flags & Py_TPFLAGS_LONG_SUBCLASS )) {
305314 long res = read_py_long (handle , offsets , task_name_addr );
306315 if (res == -1 ) {
307- PyErr_SetString (PyExc_RuntimeError , "Failed to get task name" );
316+ chain_exceptions (PyExc_RuntimeError , "Failed to get task name" );
308317 return NULL ;
309318 }
310319 return PyUnicode_FromFormat ("Task-%d" , res );
@@ -482,9 +491,6 @@ parse_task(
482491 return -1 ;
483492 }
484493
485- uintptr_t refcnt ;
486- read_ptr (handle , task_address + sizeof (Py_ssize_t ), & refcnt );
487-
488494 PyObject * result = PyList_New (0 );
489495 if (result == NULL ) {
490496 return -1 ;
@@ -1159,30 +1165,32 @@ get_all_awaited_by(PyObject* self, PyObject* args)
11591165 return 0 ;
11601166 }
11611167
1168+ PyObject * result = NULL ;
1169+
11621170 uintptr_t runtime_start_addr = _Py_RemoteDebug_GetPyRuntimeAddress (handle );
11631171 if (runtime_start_addr == 0 ) {
11641172 if (!PyErr_Occurred ()) {
11651173 PyErr_SetString (
11661174 PyExc_RuntimeError , "Failed to get .PyRuntime address" );
11671175 }
1168- return NULL ;
1176+ goto result_err ;
11691177 }
11701178 struct _Py_DebugOffsets local_debug_offsets ;
11711179
11721180 if (_Py_RemoteDebug_ReadDebugOffsets (handle , & runtime_start_addr , & local_debug_offsets )) {
1173- PyErr_SetString (PyExc_RuntimeError , "Failed to read debug offsets" );
1174- return NULL ;
1181+ chain_exceptions (PyExc_RuntimeError , "Failed to read debug offsets" );
1182+ goto result_err ;
11751183 }
11761184
11771185 struct _Py_AsyncioModuleDebugOffsets local_async_debug ;
11781186 if (read_async_debug (handle , & local_async_debug )) {
1179- PyErr_SetString (PyExc_RuntimeError , "Failed to read asyncio debug offsets" );
1180- return NULL ;
1187+ chain_exceptions (PyExc_RuntimeError , "Failed to read asyncio debug offsets" );
1188+ goto result_err ;
11811189 }
11821190
1183- PyObject * result = PyList_New (0 );
1191+ result = PyList_New (0 );
11841192 if (result == NULL ) {
1185- return NULL ;
1193+ goto result_err ;
11861194 }
11871195
11881196 uint64_t interpreter_state_list_head =
@@ -1259,7 +1267,7 @@ get_all_awaited_by(PyObject* self, PyObject* args)
12591267 return result ;
12601268
12611269result_err :
1262- Py_DECREF (result );
1270+ Py_XDECREF (result );
12631271 _Py_RemoteDebug_CleanupProcHandle (handle );
12641272 return NULL ;
12651273}
@@ -1299,7 +1307,7 @@ get_stack_trace(PyObject* self, PyObject* args)
12991307 struct _Py_DebugOffsets local_debug_offsets ;
13001308
13011309 if (_Py_RemoteDebug_ReadDebugOffsets (handle , & runtime_start_address , & local_debug_offsets )) {
1302- PyErr_SetString (PyExc_RuntimeError , "Failed to read debug offsets" );
1310+ chain_exceptions (PyExc_RuntimeError , "Failed to read debug offsets" );
13031311 goto result_err ;
13041312 }
13051313
@@ -1357,48 +1365,48 @@ get_async_stack_trace(PyObject* self, PyObject* args)
13571365 return 0 ;
13581366 }
13591367
1368+ PyObject * result = NULL ;
1369+
13601370 uintptr_t runtime_start_address = _Py_RemoteDebug_GetPyRuntimeAddress (handle );
13611371 if (runtime_start_address == 0 ) {
13621372 if (!PyErr_Occurred ()) {
13631373 PyErr_SetString (
13641374 PyExc_RuntimeError , "Failed to get .PyRuntime address" );
13651375 }
1366- return NULL ;
1376+ goto result_err ;
13671377 }
13681378 struct _Py_DebugOffsets local_debug_offsets ;
13691379
13701380 if (_Py_RemoteDebug_ReadDebugOffsets (handle , & runtime_start_address , & local_debug_offsets )) {
1371- PyErr_SetString (PyExc_RuntimeError , "Failed to read debug offsets" );
1372- return NULL ;
1381+ chain_exceptions (PyExc_RuntimeError , "Failed to read debug offsets" );
1382+ goto result_err ;
13731383 }
13741384
13751385 struct _Py_AsyncioModuleDebugOffsets local_async_debug ;
13761386 if (read_async_debug (handle , & local_async_debug )) {
1377- PyErr_SetString (PyExc_RuntimeError , "Failed to read asyncio debug offsets" );
1378- return NULL ;
1387+ chain_exceptions (PyExc_RuntimeError , "Failed to read asyncio debug offsets" );
1388+ goto result_err ;
13791389 }
13801390
1381- PyObject * result = PyList_New (1 );
1391+ result = PyList_New (1 );
13821392 if (result == NULL ) {
1383- return NULL ;
1393+ goto result_err ;
13841394 }
13851395 PyObject * calls = PyList_New (0 );
13861396 if (calls == NULL ) {
1387- Py_DECREF (result );
1388- return NULL ;
1397+ goto result_err ;
13891398 }
13901399 if (PyList_SetItem (result , 0 , calls )) { /* steals ref to 'calls' */
1391- Py_DECREF (result );
13921400 Py_DECREF (calls );
1393- return NULL ;
1401+ goto result_err ;
13941402 }
13951403
13961404 uintptr_t running_task_addr = (uintptr_t )NULL ;
13971405 if (find_running_task (
13981406 handle , runtime_start_address , & local_debug_offsets , & local_async_debug ,
13991407 & running_task_addr )
14001408 ) {
1401- PyErr_SetString (PyExc_RuntimeError , "Failed to find running task" );
1409+ chain_exceptions (PyExc_RuntimeError , "Failed to find running task" );
14021410 goto result_err ;
14031411 }
14041412
@@ -1413,7 +1421,7 @@ get_async_stack_trace(PyObject* self, PyObject* args)
14131421 running_task_addr + local_async_debug .asyncio_task_object .task_coro ,
14141422 & running_coro_addr
14151423 )) {
1416- PyErr_SetString (PyExc_RuntimeError , "Failed to read running task coro" );
1424+ chain_exceptions (PyExc_RuntimeError , "Failed to read running task coro" );
14171425 goto result_err ;
14181426 }
14191427
@@ -1443,7 +1451,7 @@ get_async_stack_trace(PyObject* self, PyObject* args)
14431451 handle , runtime_start_address , & local_debug_offsets ,
14441452 & address_of_current_frame )
14451453 ) {
1446- PyErr_SetString (PyExc_RuntimeError , "Failed to find running frame" );
1454+ chain_exceptions (PyExc_RuntimeError , "Failed to find running frame" );
14471455 goto result_err ;
14481456 }
14491457
@@ -1459,7 +1467,7 @@ get_async_stack_trace(PyObject* self, PyObject* args)
14591467 );
14601468
14611469 if (res < 0 ) {
1462- PyErr_SetString (PyExc_RuntimeError , "Failed to parse async frame object" );
1470+ chain_exceptions (PyExc_RuntimeError , "Failed to parse async frame object" );
14631471 goto result_err ;
14641472 }
14651473
@@ -1501,7 +1509,7 @@ get_async_stack_trace(PyObject* self, PyObject* args)
15011509
15021510result_err :
15031511 _Py_RemoteDebug_CleanupProcHandle (handle );
1504- Py_DECREF (result );
1512+ Py_XDECREF (result );
15051513 return NULL ;
15061514}
15071515
0 commit comments