From: Peter Krempa <[email protected]> virObject internally uses g_object which doesn't expose the internal reference count. When debug logging we log ref/unref operations but when reading logs it's hard to follow if a precise reference count is needed at some points.
Add a private reference counter variable and use it in debug messages of virObject operations. The code is designed so that it can be disabled if ever needed since it's just for debugging. For now let's keep it enabled. With all the informaton added the logs look like (timestamps trimmed): debug : virObjectRef:424 : OBJECT_REF: obj=0x7fffac001d30 classname=qemuMonitor refs=3 debug : virObjectUnref:392 : OBJECT_UNREF: obj=0x7fffac001d30 classname=qemuMonitor refs=2 debug : virObjectNew:264 : OBJECT_NEW: obj=0x7fffac00db70 classname=virDomainEventAgentLifecycle debug : virObjectUnref:392 : OBJECT_UNREF: obj=0x7fffac00db70 classname=virDomainEventAgentLifecycle refs=0 debug : vir_object_finalize:328 : OBJECT_DISPOSE: obj=0x7fffac00db70 classname=virDomainEventAgentLifecycle Signed-off-by: Peter Krempa <[email protected]> --- src/libvirt_probes.d | 4 ++-- src/util/virobject.c | 23 ++++++++++++++++++++--- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/libvirt_probes.d b/src/libvirt_probes.d index b73e9d6e82..5f029c3eb6 100644 --- a/src/libvirt_probes.d +++ b/src/libvirt_probes.d @@ -16,8 +16,8 @@ provider libvirt { # file: src/util/virobject.c # prefix: object probe object_new(void *obj, const char *klassname); - probe object_ref(void *obj, const char *klassname); - probe object_unref(void *obj, const char *klassname); + probe object_ref(void *obj, const char *klassname, int refs); + probe object_unref(void *obj, const char *klassname, int refs); probe object_dispose(void *obj, const char *klassname); # file: src/rpc/virnetsocket.c diff --git a/src/util/virobject.c b/src/util/virobject.c index 0ccaaf101e..876a04789f 100644 --- a/src/util/virobject.c +++ b/src/util/virobject.c @@ -32,6 +32,8 @@ VIR_LOG_INIT("util.object"); +#define VIR_OBJECT_DEBUG_REFCOUNT 1 + static unsigned int magicCounter = 0xCAFE0000; struct _virClass { @@ -48,6 +50,9 @@ struct _virClass { typedef struct _virObjectPrivate virObjectPrivate; struct _virObjectPrivate { virClass *klass; +#if VIR_OBJECT_DEBUG_REFCOUNT + int refs; /* Informative reference count used for PROBE and debug messages. */ +#endif /* VIR_OBJECT_DEBUG_REFCOUNT */ }; @@ -253,6 +258,9 @@ virObjectNew(virClass *klass) priv = vir_object_get_instance_private(obj); priv->klass = klass; +#if VIR_OBJECT_DEBUG_REFCOUNT + priv->refs = 1; +#endif /*VIR_OBJECT_DEBUG_REFCOUNT */ PROBE_DEBUG(OBJECT_NEW, "obj=%p classname=%s", obj, priv->klass->name); return obj; @@ -372,12 +380,17 @@ virObjectUnref(void *anyobj) { virObject *obj = anyobj; virObjectPrivate *priv; + int refs = -1; if (VIR_OBJECT_NOTVALID(obj)) return; priv = vir_object_get_instance_private(obj); - PROBE_DEBUG(OBJECT_UNREF, "obj=%p classname=%s", obj, priv->klass->name); +#if VIR_OBJECT_DEBUG_REFCOUNT + refs = g_atomic_int_add(&priv->refs, -1) - 1; +#endif /* VIR_OBJECT_DEBUG_REFCOUNT */ + PROBE_DEBUG(OBJECT_UNREF, "obj=%p classname=%s refs=%d", + obj, priv->klass->name, refs); g_object_unref(anyobj); } @@ -397,15 +410,19 @@ virObjectRef(void *anyobj) { virObject *obj = anyobj; virObjectPrivate *priv; + int refs = -1; if (VIR_OBJECT_NOTVALID(obj)) return NULL; - g_object_ref(obj); priv = vir_object_get_instance_private(obj); - PROBE_DEBUG(OBJECT_REF, "obj=%p classname=%s", obj, priv->klass->name); +#if VIR_OBJECT_DEBUG_REFCOUNT + refs = g_atomic_int_add(&priv->refs, 1) + 1; +#endif /* VIR_OBJECT_DEBUG_REFCOUNT */ + PROBE_DEBUG(OBJECT_REF, "obj=%p classname=%s refs=%d", + obj, priv->klass->name, refs); return anyobj; } -- 2.54.0
