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 @@ -1601,11 +1601,25 @@ static void
1601
1601
FutureIter_dealloc (futureiterobject * it )
1602
1602
{
1603
1603
PyTypeObject * tp = Py_TYPE (it );
1604
- asyncio_state * state = get_asyncio_state_by_def ((PyObject * )it );
1604
+
1605
+ // FutureIter is a heap type so any subclass must also be a heap type.
1606
+ assert (_PyType_HasFeature (tp , Py_TPFLAGS_HEAPTYPE ));
1607
+
1608
+ PyObject * module = ((PyHeapTypeObject * )tp )-> ht_module ;
1609
+ asyncio_state * state = NULL ;
1610
+
1605
1611
PyObject_GC_UnTrack (it );
1606
1612
tp -> tp_clear ((PyObject * )it );
1607
1613
1608
- if (state -> fi_freelist_len < FI_FREELIST_MAXLEN ) {
1614
+ // GH-115874: We can't use PyType_GetModuleByDef here as the type might have
1615
+ // already been cleared, which is also why we must check if ht_module != NULL.
1616
+ // Due to this restriction, subclasses that belong to a different module
1617
+ // will not be able to use the free list.
1618
+ if (module && _PyModule_GetDef (module ) == & _asynciomodule ) {
1619
+ state = get_asyncio_state (module );
1620
+ }
1621
+
1622
+ if (state && state -> fi_freelist_len < FI_FREELIST_MAXLEN ) {
1609
1623
state -> fi_freelist_len ++ ;
1610
1624
it -> future = (FutureObj * ) state -> fi_freelist ;
1611
1625
state -> fi_freelist = it ;
You can’t perform that action at this time.
0 commit comments