File tree 2 files changed +17
-2
lines changed
Misc/NEWS.d/next/Core and Builtins 2 files changed +17
-2
lines changed Original file line number Diff line number Diff line change
1
+ Fixed a possible segfault during garbage collection of ``_asyncio.FutureIter `` objects
Original file line number Diff line number Diff line change @@ -1590,11 +1590,25 @@ static void
1590
1590
FutureIter_dealloc (futureiterobject * it )
1591
1591
{
1592
1592
PyTypeObject * tp = Py_TYPE (it );
1593
- asyncio_state * state = get_asyncio_state_by_def ((PyObject * )it );
1593
+
1594
+ // FutureIter is a heap type so any subclass must also be a heap type.
1595
+ assert (_PyType_HasFeature (tp , Py_TPFLAGS_HEAPTYPE ));
1596
+
1597
+ PyObject * module = ((PyHeapTypeObject * )tp )-> ht_module ;
1598
+ asyncio_state * state = NULL ;
1599
+
1594
1600
PyObject_GC_UnTrack (it );
1595
1601
tp -> tp_clear ((PyObject * )it );
1596
1602
1597
- if (state -> fi_freelist_len < FI_FREELIST_MAXLEN ) {
1603
+ // GH-115874: We can't use PyType_GetModuleByDef here as the type might have
1604
+ // already been cleared, which is also why we must check if ht_module != NULL.
1605
+ // Due to this restriction, subclasses that belong to a different module
1606
+ // will not be able to use the free list.
1607
+ if (module && _PyModule_GetDef (module ) == & _asynciomodule ) {
1608
+ state = get_asyncio_state (module );
1609
+ }
1610
+
1611
+ if (state && state -> fi_freelist_len < FI_FREELIST_MAXLEN ) {
1598
1612
state -> fi_freelist_len ++ ;
1599
1613
it -> future = (FutureObj * ) state -> fi_freelist ;
1600
1614
state -> fi_freelist = it ;
You can’t perform that action at this time.
0 commit comments