From 4076377820c328e299cebc72b7353621d60110a4 Mon Sep 17 00:00:00 2001 From: Geoffrey McRae Date: Mon, 5 Feb 2024 02:46:57 +1100 Subject: [PATCH] [host] win: add comRef helpers for leak identification and tracking --- host/platform/Windows/include/com_ref.h | 13 ++++++++----- host/platform/Windows/src/com_ref.c | 21 ++++++++++++++------- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/host/platform/Windows/include/com_ref.h b/host/platform/Windows/include/com_ref.h index f9da1f6e..4ea44cc8 100644 --- a/host/platform/Windows/include/com_ref.h +++ b/host/platform/Windows/include/com_ref.h @@ -25,6 +25,7 @@ #include #include +#include "common/util.h" #include "common/locking.h" /** @@ -42,10 +43,10 @@ struct ComScope unsigned used; struct { - IUnknown *** ptr; IUnknown * ref; + const char * where; } - * refs; + *refs; void (*free)(void * ptr); }; @@ -55,7 +56,7 @@ void comRef_initScope(unsigned size, ComScope ** instance, void comRef_freeScope(ComScope ** instance); -IUnknown ** comRef_new(ComScope * scope, IUnknown *** dst); +IUnknown ** comRef_new(ComScope * scope, IUnknown *** dst, const char * where); #define comRef_initGlobalScope(size, scope) \ comRef_initScope((size), &(scope), malloc, free, true) @@ -73,11 +74,13 @@ IUnknown ** comRef_new(ComScope * scope, IUnknown *** dst); #define comRef_defineLocal(type, name) \ type ** name = NULL; \ - comRef_new(_comRef_localScope, (IUnknown ***)&(name)); + comRef_new(_comRef_localScope, (IUnknown ***)&(name), \ + STR(name)); #define _comRef_toGlobal(globalScope, dst, src) \ { \ - IUnknown ** global = comRef_new((globalScope), (IUnknown ***)&(dst)); \ + IUnknown ** global = comRef_new((globalScope), (IUnknown ***)&(dst), \ + STR(dst)); \ *global = (IUnknown *)*(src); \ *(src) = NULL; \ } diff --git a/host/platform/Windows/src/com_ref.c b/host/platform/Windows/src/com_ref.c index 74cd5d2c..a4c20b8d 100644 --- a/host/platform/Windows/src/com_ref.c +++ b/host/platform/Windows/src/com_ref.c @@ -55,12 +55,17 @@ void comRef_freeScope(ComScope ** instance) typeof(scope->refs) ref = &scope->refs[i]; if (ref->ref) { - IUnknown_Release(ref->ref); + ULONG count = IUnknown_Release(ref->ref); + +#ifdef DEBUG_COMREF + if (count > 0 && scope->free) + DEBUG_INFO("comRef %s release is %lu", ref->where, count); +#else + (void)count; +#endif + ref->ref = NULL; } - - *ref->ptr = NULL; - ref->ptr = NULL; } if (scope->threadSafe) @@ -72,7 +77,7 @@ void comRef_freeScope(ComScope ** instance) *instance = NULL; } -IUnknown ** comRef_new(ComScope * scope, IUnknown *** dst) +IUnknown ** comRef_new(ComScope * scope, IUnknown *** dst, const char * where) { /* check if the value it points to is already in our memory range and if it * does, then reuse it */ @@ -97,8 +102,10 @@ IUnknown ** comRef_new(ComScope * scope, IUnknown *** dst) if (scope->threadSafe) LG_LOCK(scope->lock); - scope->refs[scope->used].ptr = dst; - *dst = &scope->refs[scope->used].ref; + typeof(scope->refs[0]) * ref = &scope->refs[scope->used]; + ref->where = where; + *dst = &ref->ref; + ++scope->used; if (scope->threadSafe)