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