This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author vstinner
Recipients Mark.Shannon, christian.heimes, jdemeyer, lukasz.langa, pablogsal, petr.viktorin, pitrou, vstinner
Date 2019-09-02.21:49:58
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <>
This bug is quite complex. Let me try to explain it more simply.

* Create an object A
* Create a weak reference to A with a callback CB
* A and CB are part of a reference cycle
* Removing the last references to A and CB are not enough to destroy them
* Trigger a garbage collection to break the cycle
* A and CB are seen as unreachable by the GC
* The GC "clears" CB which makes CB inconsistent (tp_clear)
* A is deleted which calls CB
* Crash on calling inconsistent CB


In the case of FreeIPA:

* A is a _cffi_backend.CTypeDescr instance
* CB is the remove() function defined in weakref.WeakValueDictionary constructor

The FreeIPA reference cycle is quite complex:

-> remove().__closure__ (tuple)
-> (dict) = remove().__closure__[0]
-> weakref.KeyedRef
-> (<str 1>, <tuple 2>)
-> (<CTypeDescrObject 3>,) = <tuple 2>
-> <CTypeDescrObject 3>
-> {'C_Initialize': ..., 'C_CreateObject': ..., 'C_Finalize': ...} (dict)
-> <_cffi_backend.CField 4>
-> <_cffi_backend.CTypeDescr 5>
-> remove() = callback of a weak reference to <_cffi_backend.CTypeDescr 5>

<_cffi_backend.CField 4> is not seen as unreachable by the GC because CField_Type.tp_traverse is not implemented (and CField_Type doesn't use Py_TPFLAGS_HAVE_GC flag).
Date User Action Args
2019-09-02 21:49:58vstinnersetrecipients: + vstinner, pitrou, christian.heimes, petr.viktorin, lukasz.langa, Mark.Shannon, jdemeyer, pablogsal
2019-09-02 21:49:58vstinnersetmessageid: <>
2019-09-02 21:49:58vstinnerlinkissue38006 messages
2019-09-02 21:49:58vstinnercreate