@@ -1218,23 +1218,45 @@ dump_frame(int fd, _PyInterpreterFrame *frame)
1218
1218
PUTS (fd , "\n" );
1219
1219
}
1220
1220
1221
+ static int
1222
+ tstate_is_freed (PyThreadState * tstate )
1223
+ {
1224
+ if (_PyMem_IsPtrFreed (tstate )) {
1225
+ return 1 ;
1226
+ }
1227
+ if (_PyMem_IsPtrFreed (tstate -> interp )) {
1228
+ return 1 ;
1229
+ }
1230
+ return 0 ;
1231
+ }
1232
+
1233
+
1234
+ static int
1235
+ interp_is_freed (PyInterpreterState * interp )
1236
+ {
1237
+ return _PyMem_IsPtrFreed (interp );
1238
+ }
1239
+
1240
+
1221
1241
static void
1222
1242
dump_traceback (int fd , PyThreadState * tstate , int write_header )
1223
1243
{
1224
- _PyInterpreterFrame * frame ;
1225
- unsigned int depth ;
1226
-
1227
1244
if (write_header ) {
1228
1245
PUTS (fd , "Stack (most recent call first):\n" );
1229
1246
}
1230
1247
1231
- frame = tstate -> cframe -> current_frame ;
1248
+ if (tstate_is_freed (tstate )) {
1249
+ PUTS (fd , " <tstate is freed>\n" );
1250
+ return ;
1251
+ }
1252
+
1253
+ _PyInterpreterFrame * frame = tstate -> cframe -> current_frame ;
1232
1254
if (frame == NULL ) {
1233
1255
PUTS (fd , " <no Python frame>\n" );
1234
1256
return ;
1235
1257
}
1236
1258
1237
- depth = 0 ;
1259
+ unsigned int depth = 0 ;
1238
1260
while (1 ) {
1239
1261
if (MAX_FRAME_DEPTH <= depth ) {
1240
1262
PUTS (fd , " ...\n" );
@@ -1298,9 +1320,6 @@ const char*
1298
1320
_Py_DumpTracebackThreads (int fd , PyInterpreterState * interp ,
1299
1321
PyThreadState * current_tstate )
1300
1322
{
1301
- PyThreadState * tstate ;
1302
- unsigned int nthreads ;
1303
-
1304
1323
if (current_tstate == NULL ) {
1305
1324
/* _Py_DumpTracebackThreads() is called from signal handlers by
1306
1325
faulthandler.
@@ -1316,6 +1335,10 @@ _Py_DumpTracebackThreads(int fd, PyInterpreterState *interp,
1316
1335
current_tstate = PyGILState_GetThisThreadState ();
1317
1336
}
1318
1337
1338
+ if (current_tstate != NULL && tstate_is_freed (current_tstate )) {
1339
+ return "tstate is freed" ;
1340
+ }
1341
+
1319
1342
if (interp == NULL ) {
1320
1343
if (current_tstate == NULL ) {
1321
1344
interp = _PyGILState_GetInterpreterStateUnsafe ();
@@ -1330,14 +1353,18 @@ _Py_DumpTracebackThreads(int fd, PyInterpreterState *interp,
1330
1353
}
1331
1354
assert (interp != NULL );
1332
1355
1356
+ if (interp_is_freed (interp )) {
1357
+ return "interp is freed" ;
1358
+ }
1359
+
1333
1360
/* Get the current interpreter from the current thread */
1334
- tstate = PyInterpreterState_ThreadHead (interp );
1361
+ PyThreadState * tstate = PyInterpreterState_ThreadHead (interp );
1335
1362
if (tstate == NULL )
1336
1363
return "unable to get the thread head state" ;
1337
1364
1338
1365
/* Dump the traceback of each thread */
1339
1366
tstate = PyInterpreterState_ThreadHead (interp );
1340
- nthreads = 0 ;
1367
+ unsigned int nthreads = 0 ;
1341
1368
_Py_BEGIN_SUPPRESS_IPH
1342
1369
do
1343
1370
{
0 commit comments