12
12
#include "pycore_parser.h" // _PyParser_ASTFromString
13
13
#include "pycore_pyarena.h" // _PyArena_Free()
14
14
#include "pycore_pyerrors.h" // _PyErr_Fetch()
15
+ #include "pycore_pymem.h" // _PyMem_IsPtrFreed()
15
16
#include "pycore_pystate.h" // _PyThreadState_GET()
16
17
#include "pycore_traceback.h" // EXCEPTION_TB_HEADER
17
18
@@ -1234,23 +1235,45 @@ dump_frame(int fd, _PyInterpreterFrame *frame)
1234
1235
PUTS (fd , "\n" );
1235
1236
}
1236
1237
1238
+ static int
1239
+ tstate_is_freed (PyThreadState * tstate )
1240
+ {
1241
+ if (_PyMem_IsPtrFreed (tstate )) {
1242
+ return 1 ;
1243
+ }
1244
+ if (_PyMem_IsPtrFreed (tstate -> interp )) {
1245
+ return 1 ;
1246
+ }
1247
+ return 0 ;
1248
+ }
1249
+
1250
+
1251
+ static int
1252
+ interp_is_freed (PyInterpreterState * interp )
1253
+ {
1254
+ return _PyMem_IsPtrFreed (interp );
1255
+ }
1256
+
1257
+
1237
1258
static void
1238
1259
dump_traceback (int fd , PyThreadState * tstate , int write_header )
1239
1260
{
1240
- _PyInterpreterFrame * frame ;
1241
- unsigned int depth ;
1242
-
1243
1261
if (write_header ) {
1244
1262
PUTS (fd , "Stack (most recent call first):\n" );
1245
1263
}
1246
1264
1247
- frame = tstate -> cframe -> current_frame ;
1265
+ if (tstate_is_freed (tstate )) {
1266
+ PUTS (fd , " <tstate is freed>\n" );
1267
+ return ;
1268
+ }
1269
+
1270
+ _PyInterpreterFrame * frame = tstate -> cframe -> current_frame ;
1248
1271
if (frame == NULL ) {
1249
1272
PUTS (fd , " <no Python frame>\n" );
1250
1273
return ;
1251
1274
}
1252
1275
1253
- depth = 0 ;
1276
+ unsigned int depth = 0 ;
1254
1277
while (1 ) {
1255
1278
if (MAX_FRAME_DEPTH <= depth ) {
1256
1279
PUTS (fd , " ...\n" );
@@ -1305,9 +1328,6 @@ const char*
1305
1328
_Py_DumpTracebackThreads (int fd , PyInterpreterState * interp ,
1306
1329
PyThreadState * current_tstate )
1307
1330
{
1308
- PyThreadState * tstate ;
1309
- unsigned int nthreads ;
1310
-
1311
1331
if (current_tstate == NULL ) {
1312
1332
/* _Py_DumpTracebackThreads() is called from signal handlers by
1313
1333
faulthandler.
@@ -1323,6 +1343,10 @@ _Py_DumpTracebackThreads(int fd, PyInterpreterState *interp,
1323
1343
current_tstate = PyGILState_GetThisThreadState ();
1324
1344
}
1325
1345
1346
+ if (current_tstate != NULL && tstate_is_freed (current_tstate )) {
1347
+ return "tstate is freed" ;
1348
+ }
1349
+
1326
1350
if (interp == NULL ) {
1327
1351
if (current_tstate == NULL ) {
1328
1352
interp = _PyGILState_GetInterpreterStateUnsafe ();
@@ -1337,14 +1361,18 @@ _Py_DumpTracebackThreads(int fd, PyInterpreterState *interp,
1337
1361
}
1338
1362
assert (interp != NULL );
1339
1363
1364
+ if (interp_is_freed (interp )) {
1365
+ return "interp is freed" ;
1366
+ }
1367
+
1340
1368
/* Get the current interpreter from the current thread */
1341
- tstate = PyInterpreterState_ThreadHead (interp );
1369
+ PyThreadState * tstate = PyInterpreterState_ThreadHead (interp );
1342
1370
if (tstate == NULL )
1343
1371
return "unable to get the thread head state" ;
1344
1372
1345
1373
/* Dump the traceback of each thread */
1346
1374
tstate = PyInterpreterState_ThreadHead (interp );
1347
- nthreads = 0 ;
1375
+ unsigned int nthreads = 0 ;
1348
1376
_Py_BEGIN_SUPPRESS_IPH
1349
1377
do
1350
1378
{
0 commit comments