diff options
author | Jose Fonseca <jfonseca@vmware.com> | 2016-06-28 22:25:43 +0100 |
---|---|---|
committer | Jose Fonseca <jfonseca@vmware.com> | 2016-06-28 22:25:43 +0100 |
commit | c04e1899c4434c1d49102254952a400f4223212d (patch) | |
tree | fbd502ade1cc651dfce5e770daf60054f6972099 /wrappers | |
parent | 9c34aeb5643b68789ba0e2d5ded62d934dcbf464 (diff) |
trace: Don't presume that COM interface pointers are freed when refcount reaches zero.
They often aren't. And worst of all, some apps rely on them sticking
around.
With this change, the destruction of wrapper objects is effectively
deferred until a different interface is created on the same pointer
address, or more likely leaked. But this is unavoidable, given there's
no generic mechanism to know for sure when the wrapped object is freed.
Fixes https://github.com/apitrace/apitrace/issues/462
Diffstat (limited to 'wrappers')
-rw-r--r-- | wrappers/trace.py | 10 |
1 files changed, 7 insertions, 3 deletions
diff --git a/wrappers/trace.py b/wrappers/trace.py index 18c8816e..6773f7e2 100644 --- a/wrappers/trace.py +++ b/wrappers/trace.py @@ -801,13 +801,16 @@ class Tracer: print r' Wrap%s *pWrapper = (Wrap%s *)it->second;' % (iface.name, iface.name) print r' assert(pWrapper);' print r' assert(pWrapper->m_dwMagic == 0xd8365d6c);' - print r' assert(pWrapper->m_pInstance == pObj);' - print r' if (pWrapper->m_pVtbl == getVtbl(pObj) &&' + print r' if (pWrapper->m_pInstance == pObj &&' + print r' pWrapper->m_pVtbl == getVtbl(pObj) &&' print r' pWrapper->m_NumMethods >= %s) {' % len(baseMethods) if debug: print r' os::log("%s: fetched pvObj=%p pWrapper=%p pVtbl=%p\n", entryName, pObj, pWrapper, pWrapper->m_pVtbl);' + print r' assert(hasChildInterface(IID_%s, pWrapper->m_pInstance));' % iface.name print r' *ppObj = pWrapper;' print r' return;' + print r' } else {' + print r' delete pWrapper;' print r' }' print r' }' for childIface in getInterfaceHierarchy(ifaces, iface): @@ -903,7 +906,8 @@ class Tracer: if method.name == 'Release': assert method.type is not stdapi.Void print r' if (!_result) {' - print r' delete this;' + print r' // NOTE: Must not delete the wrapper here. See' + print r' // https://github.com/apitrace/apitrace/issues/462' print r' }' print ' trace::localWriter.endLeave();' |