summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJose Fonseca <jfonseca@vmware.com>2016-06-28 22:25:43 +0100
committerJose Fonseca <jfonseca@vmware.com>2016-06-28 22:25:43 +0100
commitc04e1899c4434c1d49102254952a400f4223212d (patch)
treefbd502ade1cc651dfce5e770daf60054f6972099
parent9c34aeb5643b68789ba0e2d5ded62d934dcbf464 (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
-rw-r--r--wrappers/trace.py10
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();'