@@ -181,8 +181,11 @@ CFunction::CFunction(unsigned long ulAddr, Convention_t eCallingConvention,
181181
182182CFunction::~CFunction ()
183183{
184+ if (!m_pCallingConvention)
185+ return ;
186+
184187 // If the convention isn't flagged as hooked, then we need to take care of it.
185- if (m_pCallingConvention && !m_pCallingConvention->m_bHooked )
188+ if (!m_pCallingConvention->m_bHooked )
186189 {
187190 // If we don't have a Python instance, then we can safely delete it.
188191 if (m_oCallingConvention.is_none ())
@@ -191,6 +194,10 @@ CFunction::~CFunction()
191194 else if (Py_REFCNT (m_oCallingConvention.ptr ()) > 1 )
192195 Py_DECREF (m_oCallingConvention.ptr ());
193196 }
197+ // If we are using a built-in convention that is currently hooked, let's flag it as no longer hooked
198+ // so that we know we are not bound to a CFunction anymore and can be deleted.
199+ else if (m_eCallingConvention != CONV_CUSTOM && !dynamic_cast <ICallingConventionWrapper *>(m_pCallingConvention))
200+ m_pCallingConvention->m_bHooked = false ;
194201
195202 m_pCallingConvention = NULL ;
196203}
@@ -424,17 +431,24 @@ void CFunction::DeleteHook()
424431
425432 g_mapCallbacks.erase (pHook);
426433
427- // Flag the convention as no longer hooked and being taken care of by DynamicHooks.
428- pHook->m_pCallingConvention ->m_bHooked = false ;
429-
430- // Release the Python reference we reserved for DynamicHooks.
431434 ICallingConventionWrapper *pConv = dynamic_cast <ICallingConventionWrapper *>(pHook->m_pCallingConvention );
432435 if (pConv)
433436 {
434- PyObject *pOwner = detail::wrapper_base_::owner (pConv);
435- if (pOwner && Py_REFCNT (pOwner))
436- Py_DECREF (pOwner);
437+ if (pConv->m_bHooked )
438+ {
439+ // Flag the convention as no longer hooked and being taken care of by DynamicHooks.
440+ pHook->m_pCallingConvention ->m_bHooked = false ;
441+
442+ // Release the Python reference we reserved for DynamicHooks.
443+ PyObject *pOwner = detail::wrapper_base_::owner (pConv);
444+ if (pOwner && Py_REFCNT (pOwner))
445+ Py_DECREF (pOwner);
446+ }
437447 }
448+ // If we are a built-in convention bound to a CHook instance but not flagged as hooked anymore, then that
449+ // means we are no longer bound to a CFunction instance and can be safely deleted.
450+ else if (!pHook->m_pCallingConvention ->m_bHooked )
451+ delete pHook->m_pCallingConvention ;
438452
439453 // Set the calling convention to NULL, because DynamicHooks will delete it otherwise.
440454 pHook->m_pCallingConvention = NULL ;
0 commit comments