a patch for runtime debugging control for libbonobo
- From: Jaka Mocnik <jaka gnu org>
- To: gnome-components-list <gnome-components-list gnome org>
- Cc: michael ximian com
- Subject: a patch for runtime debugging control for libbonobo
- Date: 13 May 2002 23:36:20 +0200
hello!
attached is a patch that enables control of debugging output via an
environment variable BONOBO_DEBUG_FLAGS, in a manner similar to ORBit2:
BONOBO_DEBUG_FLAGS=[object|running|refs|aggregate|lifecycle]{:[object|running|refs|aggregate|lifecycle]}*
each flag controls output in a different part of libbonobo that was
previously conditionally compiled if symbol BONOBO_*_HOOKS was defined.
additionaly, if BONOBO_DEBUG_DIR is defined, the debugging output is
sent to a file in that directory, named bonobo-debug-<pid>. otherwise it
just goes to stdout.
the patch patches Makefile.am, bonobo-object.c and
bonobo-running-context.c. it adds two new files bonobo-debug.c and
bonobo-debug.h. the latter header is private and is not installed.
it helped a lot when debugging ref counting in GGV. if it seems helpful,
it might be included in the library. otherwise, I'll just keep it in my
private tree.
regards,
jaKa
--
email: jaka gnu org
w3: http://pluton.ijs.si/~jaka
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/**
* bonobo-debug.c: A runtime-controllable debugging API.
*
* Author:
* Jaka Mocnik <jaka gnu org>
*/
#include <stdio.h>
#include <unistd.h>
#include <glib.h>
#include <bonobo/bonobo-debug.h>
BonoboDebugFlags _bonobo_debug_flags;
static FILE *_bonobo_debug_file;
void
bonobo_debug_init()
{
static GDebugKey debug_keys[] = {
{ "refs", BONOBO_DEBUG_REFS },
{ "aggregate", BONOBO_DEBUG_AGGREGATE },
{ "lifecycle", BONOBO_DEBUG_LIFECYCLE },
{ "running", BONOBO_DEBUG_RUNNING },
{ "object", BONOBO_DEBUG_OBJECT },
};
const char *env_string;
_bonobo_debug_flags = BONOBO_DEBUG_NONE;
env_string = g_getenv ("BONOBO_DEBUG_FLAGS");
if (env_string)
_bonobo_debug_flags |=
g_parse_debug_string (env_string,
debug_keys,
G_N_ELEMENTS (debug_keys));
_bonobo_debug_file = NULL;
env_string = g_getenv ("BONOBO_DEBUG_DIR");
if(env_string) {
gchar *dbg_filename;
dbg_filename = g_strdup_printf("%s/bonobo-debug-%d", env_string, getpid());
_bonobo_debug_file = fopen(dbg_filename, "w");
g_free(dbg_filename);
}
if(_bonobo_debug_file == NULL)
_bonobo_debug_file = stdout;
}
void
bonobo_debug_print (char *name, char *fmt, ...)
{
va_list args;
va_start (args, fmt);
fprintf (_bonobo_debug_file, "[%06d]:%-15s ", getpid (), name);
vfprintf (_bonobo_debug_file, fmt, args);
fprintf (_bonobo_debug_file, "\n");
fflush (_bonobo_debug_file);
va_end (args);
}
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/**
* bonobo-debug.c: A runtime-controllable debugging API.
*
* Author:
* Jaka Mocnik <jaka gnu org>
*/
#ifndef _BONOBO_DEBUG_H_
#define _BONOBO_DEBUG_H_
typedef enum {
BONOBO_DEBUG_NONE = 0,
BONOBO_DEBUG_REFS = 1 << 0,
BONOBO_DEBUG_AGGREGATE = 1 << 1,
BONOBO_DEBUG_LIFECYCLE = 1 << 2,
BONOBO_DEBUG_RUNNING = 1 << 3,
BONOBO_DEBUG_OBJECT = 1 << 4
} BonoboDebugFlags;
extern BonoboDebugFlags _bonobo_debug_flags;
void bonobo_debug_init (void);
void bonobo_debug_print (char *name, char *fmt, ...);
#endif /* _BONOBO_DEBUG_H_ */
Index: bonobo/Makefile.am
===================================================================
RCS file: /cvs/gnome/libbonobo/bonobo/Makefile.am,v
retrieving revision 1.61
diff -u -r1.61 Makefile.am
--- bonobo/Makefile.am 16 Feb 2002 16:48:40 -0000 1.61
+++ bonobo/Makefile.am 13 May 2002 21:34:17 -0000
@@ -121,7 +121,9 @@
bonobo-stream-memory.c \
bonobo-storage-memory.c \
bonobo-running-context.c \
- bonobo-types.c
+ bonobo-types.c \
+ bonobo-debug.c \
+ bonobo-debug.h
$(libbonobo_2_la_OBJECTS): Bonobo.h $(marshal_sources)
Index: bonobo/bonobo-object.c
===================================================================
RCS file: /cvs/gnome/libbonobo/bonobo/bonobo-object.c,v
retrieving revision 1.144
diff -u -r1.144 bonobo-object.c
--- bonobo/bonobo-object.c 14 Feb 2002 16:31:21 -0000 1.144
+++ bonobo/bonobo-object.c 13 May 2002 21:34:22 -0000
@@ -12,6 +12,7 @@
#include <config.h>
#include <stdio.h>
#include <string.h>
+#include <unistd.h>
#include <glib-object.h>
#include <gobject/gmarshal.h>
#include <bonobo/Bonobo.h>
@@ -23,41 +24,29 @@
#include <bonobo/bonobo-marshal.h>
#include <bonobo/bonobo-types.h>
#include <bonobo/bonobo-shutdown.h>
+#include <bonobo/bonobo-debug.h>
/* Some simple tracking - always on */
static GMutex *bonobo_total_aggregates_lock = NULL;
static glong bonobo_total_aggregates = 0;
static glong bonobo_total_aggregate_refs = 0;
-#ifdef BONOBO_OBJECT_DEBUG
-# define BONOBO_REF_HOOKS
-#endif
-
-/* Define to debug user aggregate merging code */
-#undef BONOBO_AGGREGATE_DEBUG
-
-/* NB. for a quicker debugging experience define this */
-#undef BONOBO_REF_HOOKS
-
-/* You almost certainly don't want this */
-#undef BONOBO_LIFECYCLE_DEBUG
+/* you may debug by setting BONOBO_DEBUG_FLAGS environment variable to
+ a colon separated list of a subset of {refs,aggregate,lifecycle} */
-#ifdef BONOBO_REF_HOOKS
typedef struct {
const char *fn;
gboolean ref;
int line;
} BonoboDebugRefData;
-#endif
typedef struct {
int ref_count;
gboolean immortal;
GList *objs;
-#ifdef BONOBO_REF_HOOKS
+ /* the following is required for reference debugging */
GList *refs;
int destroyed;
-#endif
} BonoboAggregateObject;
struct _BonoboObjectPrivate {
@@ -73,25 +62,8 @@
static guint bonobo_object_signals [LAST_SIGNAL];
static GObjectClass *bonobo_object_parent_class;
-#ifdef BONOBO_REF_HOOKS
-
static GHashTable *living_ao_ht = NULL;
-static void
-bonobo_debug_print (char *name, char *fmt, ...)
-{
- va_list args;
-
- va_start (args, fmt);
-
- printf ("[%06d]:%-15s ", getpid (), name);
- vprintf (fmt, args);
- printf ("\n");
-
- va_end (args);
-}
-#endif /* BONOBO_REF_HOOKS */
-
/* Do not use this function, it is not what you want; see unref */
static void
bonobo_object_destroy (BonoboAggregateObject *ao)
@@ -110,9 +82,8 @@
} else
g_warning ("Serious ref-counting error [%p]", o);
}
-#ifdef BONOBO_REF_HOOKS
- ao->destroyed = TRUE;
-#endif
+ if(_bonobo_debug_flags & BONOBO_DEBUG_REFS)
+ ao->destroyed = TRUE;
}
static void
@@ -121,9 +92,9 @@
CORBA_Environment ev;
PortableServer_ObjectId *oid;
-#ifdef BONOBO_LIFECYCLE_DEBUG
- g_warning ("BonoboObject corba deactivate %p", object);
-#endif
+ if(_bonobo_debug_flags & BONOBO_DEBUG_LIFECYCLE)
+ bonobo_debug_print("deactivate",
+ "BonoboObject corba deactivate %p", object);
g_assert (object->priv->ao == NULL);
@@ -167,16 +138,16 @@
g_error ("Serious bonobo object corruption");
else {
g_assert (BONOBO_OBJECT (o)->priv->ao != NULL);
-#ifdef BONOBO_REF_HOOKS
- g_assert (BONOBO_OBJECT (o)->priv->ao->destroyed);
+ if(_bonobo_debug_flags & BONOBO_DEBUG_REFS) {
+ g_assert (BONOBO_OBJECT (o)->priv->ao->destroyed);
- bonobo_debug_print ("finalize",
- "[%p] %-20s corba_objref=[%p]"
- " g_ref_count=%d", o,
- G_OBJECT_TYPE_NAME (o),
- BONOBO_OBJECT (o)->corba_objref,
- G_OBJECT (o)->ref_count);
-#endif
+ bonobo_debug_print ("finalize",
+ "[%p] %-20s corba_objref=[%p]"
+ " g_ref_count=%d", o,
+ G_OBJECT_TYPE_NAME (o),
+ BONOBO_OBJECT (o)->corba_objref,
+ G_OBJECT (o)->ref_count);
+ }
/*
* Disconnect the GObject from the aggregate object
@@ -192,20 +163,21 @@
bonobo_object_corba_deactivate (BONOBO_OBJECT (o));
g_object_unref (o);
-#ifdef BONOBO_LIFECYCLE_DEBUG
- g_warning ("Done finalize internal on %p", o);
-#endif
+ if(_bonobo_debug_flags & BONOBO_DEBUG_LIFECYCLE)
+ bonobo_debug_print ("finalize",
+ "Done finalize internal on %p",
+ o);
}
}
g_list_free (ao->objs);
ao->objs = NULL;
-#ifdef BONOBO_REF_HOOKS
- for (l = ao->refs; l; l = l->next)
- g_free (l->data);
- g_list_free (ao->refs);
-#endif
+ if(_bonobo_debug_flags & BONOBO_DEBUG_REFS) {
+ for (l = ao->refs; l; l = l->next)
+ g_free (l->data);
+ g_list_free (ao->refs);
+ }
g_free (ao);
@@ -231,9 +203,10 @@
{
BonoboObject *object = bonobo_object(servant);
-#ifdef BONOBO_LIFECYCLE_DEBUG
- g_warning ("BonoboObject Servant finalize %p", object);
-#endif
+ if(_bonobo_debug_flags & BONOBO_DEBUG_LIFECYCLE)
+ bonobo_debug_print ("finalize",
+ "BonoboObject Servant finalize %p",
+ object);
g_object_unref (G_OBJECT (object));
}
@@ -256,14 +229,13 @@
g_return_val_if_fail (BONOBO_IS_OBJECT (object), object);
g_return_val_if_fail (object->priv->ao->ref_count > 0, object);
-#ifdef BONOBO_REF_HOOKS
- bonobo_object_trace_refs (object, "local", 0, TRUE);
-#else
- if (!object->priv->ao->immortal) {
+ if(_bonobo_debug_flags & BONOBO_DEBUG_REFS) {
+ bonobo_object_trace_refs (object, "local", 0, TRUE);
+ }
+ else if (!object->priv->ao->immortal) {
object->priv->ao->ref_count++;
bonobo_total_aggregate_refs++;
}
-#endif
return object;
}
@@ -280,33 +252,33 @@
gpointer
bonobo_object_unref (gpointer obj)
{
-#ifndef BONOBO_REF_HOOKS
- BonoboAggregateObject *ao;
- BonoboObject *object = obj;
+ if(!(_bonobo_debug_flags & BONOBO_DEBUG_REFS)) {
+ BonoboAggregateObject *ao;
+ BonoboObject *object = obj;
- if (!object)
- return NULL;
+ if (!object)
+ return NULL;
- g_return_val_if_fail (BONOBO_IS_OBJECT (object), NULL);
+ g_return_val_if_fail (BONOBO_IS_OBJECT (object), NULL);
- ao = object->priv->ao;
- g_return_val_if_fail (ao != NULL, NULL);
- g_return_val_if_fail (ao->ref_count > 0, NULL);
-
- if (!ao->immortal) {
- if (ao->ref_count == 1)
- bonobo_object_destroy (ao);
+ ao = object->priv->ao;
+ g_return_val_if_fail (ao != NULL, NULL);
+ g_return_val_if_fail (ao->ref_count > 0, NULL);
- ao->ref_count--;
- bonobo_total_aggregate_refs--;
+ if (!ao->immortal) {
+ if (ao->ref_count == 1)
+ bonobo_object_destroy (ao);
+
+ ao->ref_count--;
+ bonobo_total_aggregate_refs--;
- if (ao->ref_count == 0)
- bonobo_object_finalize_internal (ao);
+ if (ao->ref_count == 0)
+ bonobo_object_finalize_internal (ao);
+ }
+ return NULL;
}
- return NULL;
-#else
- return bonobo_object_trace_refs (obj, "local", 0, FALSE);
-#endif /* BONOBO_REF_HOOKS */
+ else
+ return bonobo_object_trace_refs (obj, "local", 0, FALSE);
}
#endif /* bonobo_object_unref */
@@ -316,89 +288,87 @@
int line,
gboolean ref)
{
-#ifdef BONOBO_REF_HOOKS
- BonoboObject *object = obj;
- BonoboAggregateObject *ao;
- BonoboDebugRefData *descr;
+ if(_bonobo_debug_flags & BONOBO_DEBUG_REFS) {
+ BonoboObject *object = obj;
+ BonoboAggregateObject *ao;
+ BonoboDebugRefData *descr;
- if (!object)
- return NULL;
+ if (!object)
+ return NULL;
- g_return_val_if_fail (BONOBO_IS_OBJECT (object), ref ? object : NULL);
- ao = object->priv->ao;
- g_return_val_if_fail (ao != NULL, ref ? object : NULL);
-
- descr = g_new (BonoboDebugRefData, 1);
- ao->refs = g_list_prepend (ao->refs, descr);
- descr->fn = fn;
- descr->ref = ref;
- descr->line = line;
-
- if (ref) {
- g_return_val_if_fail (ao->ref_count > 0, object);
-
- if (!object->priv->ao->immortal) {
- object->priv->ao->ref_count++;
- bonobo_total_aggregate_refs++;
- }
+ g_return_val_if_fail (BONOBO_IS_OBJECT (object), ref ? object : NULL);
+ ao = object->priv->ao;
+ g_return_val_if_fail (ao != NULL, ref ? object : NULL);
- bonobo_debug_print ("ref", "[%p]:[%p]:%s to %d at %s:%d",
- object, ao,
- G_OBJECT_TYPE_NAME (object),
- ao->ref_count, fn, line);
-
- return object;
-
- } else { /* unref */
- bonobo_debug_print ("unref", "[%p]:[%p]:%s from %d at %s:%d",
- object, ao,
- G_OBJECT_TYPE_NAME (object),
- ao->ref_count, fn, line);
-
- g_return_val_if_fail (ao->ref_count > 0, NULL);
-
- if (ao->immortal)
- bonobo_debug_print ("unusual", "immortal object");
- else {
- if (ao->ref_count == 1) {
- bonobo_object_destroy (ao);
-
- g_return_val_if_fail (ao->ref_count > 0, NULL);
+ descr = g_new (BonoboDebugRefData, 1);
+ ao->refs = g_list_prepend (ao->refs, descr);
+ descr->fn = fn;
+ descr->ref = ref;
+ descr->line = line;
+
+ if (ref) {
+ g_return_val_if_fail (ao->ref_count > 0, object);
+
+ if (!object->priv->ao->immortal) {
+ object->priv->ao->ref_count++;
+ bonobo_total_aggregate_refs++;
}
-
- /*
- * If this blows it is likely some loony used
- * g_object_unref somewhere instead of
- * bonobo_object_unref, send them my regards.
- */
- g_assert (object->priv->ao == ao);
-
- ao->ref_count--;
- bonobo_total_aggregate_refs--;
-
- if (ao->ref_count == 0) {
+
+ bonobo_debug_print ("ref", "[%p]:[%p]:%s to %d at %s:%d",
+ object, ao,
+ G_OBJECT_TYPE_NAME (object),
+ ao->ref_count, fn, line);
+
+ return object;
+ } else { /* unref */
+ bonobo_debug_print ("unref", "[%p]:[%p]:%s from %d at %s:%d",
+ object, ao,
+ G_OBJECT_TYPE_NAME (object),
+ ao->ref_count, fn, line);
+
+ g_return_val_if_fail (ao->ref_count > 0, NULL);
+
+ if (ao->immortal)
+ bonobo_debug_print ("unusual", "immortal object");
+ else {
+ if (ao->ref_count == 1) {
+ bonobo_object_destroy (ao);
+
+ g_return_val_if_fail (ao->ref_count > 0, NULL);
+ }
- g_assert (g_hash_table_lookup (living_ao_ht, ao) == ao);
- g_hash_table_remove (living_ao_ht, ao);
+ /*
+ * If this blows it is likely some loony used
+ * g_object_unref somewhere instead of
+ * bonobo_object_unref, send them my regards.
+ */
+ g_assert (object->priv->ao == ao);
- bonobo_object_finalize_internal (ao);
+ ao->ref_count--;
+ bonobo_total_aggregate_refs--;
- } else if (ao->ref_count < 0) {
- bonobo_debug_print ("unusual",
- "[%p] already finalized", ao);
+ if (ao->ref_count == 0) {
+
+ g_assert (g_hash_table_lookup (living_ao_ht, ao) == ao);
+ g_hash_table_remove (living_ao_ht, ao);
+
+ bonobo_object_finalize_internal (ao);
+
+ } else if (ao->ref_count < 0) {
+ bonobo_debug_print ("unusual",
+ "[%p] already finalized", ao);
+ }
}
+
+ return NULL;
}
-
- return NULL;
}
-#else
- if (ref)
+ else if (ref)
return bonobo_object_ref (obj);
else {
bonobo_object_unref (obj);
return NULL;
}
-#endif
}
static void
@@ -408,11 +378,15 @@
object = bonobo_object_from_servant (servant);
-#if defined(BONOBO_REF_HOOKS) && !defined(bonobo_object_ref)
- bonobo_object_trace_refs (object, "remote", 0, TRUE);
+ if(_bonobo_debug_flags & BONOBO_DEBUG_REFS) {
+#ifndef bonobo_object_ref
+ bonobo_object_trace_refs (object, "remote", 0, TRUE);
#else
- bonobo_object_ref (object);
+ bonobo_object_ref (object);
#endif
+ }
+ else
+ bonobo_object_ref (object);
}
void
@@ -508,11 +482,15 @@
object = bonobo_object_from_servant (servant);
-#if defined(BONOBO_REF_HOOKS) && !defined(bonobo_object_unref)
- bonobo_object_trace_refs (object, "remote", 0, FALSE);
+ if(_bonobo_debug_flags & BONOBO_DEBUG_REFS) {
+#ifndef bonobo_object_unref
+ bonobo_object_trace_refs (object, "remote", 0, FALSE);
#else
- bonobo_object_unref (object);
+ bonobo_object_unref (object);
#endif
+ }
+ else
+ bonobo_object_unref (object);
}
/**
@@ -569,13 +547,13 @@
local_interface = bonobo_object_query_local_interface (
object, repoid);
-#ifdef BONOBO_REF_HOOKS
- bonobo_debug_print ("query-interface",
- "[%p]:[%p]:%s repoid=%s",
- object, object->priv->ao,
- G_OBJECT_TYPE_NAME (object),
- repoid);
-#endif
+ if(_bonobo_debug_flags & BONOBO_DEBUG_REFS) {
+ bonobo_debug_print ("query-interface",
+ "[%p]:[%p]:%s repoid=%s",
+ object, object->priv->ao,
+ G_OBJECT_TYPE_NAME (object),
+ repoid);
+ }
if (local_interface == NULL)
return CORBA_OBJECT_NIL;
@@ -596,9 +574,11 @@
{
BonoboObject *object = (BonoboObject *) gobject;
-#ifdef BONOBO_LIFECYCLE_DEBUG
- g_warning ("Bonobo Object finalize GObject %p", gobject);
-#endif
+ if(_bonobo_debug_flags & BONOBO_DEBUG_LIFECYCLE)
+ bonobo_debug_print ("finalize",
+ "Bonobo Object finalize GObject %p",
+ gobject);
+
if (object->priv->ao != NULL)
g_error ("g_object_unreffing a bonobo_object that "
"still has %d refs", object->priv->ao->ref_count);
@@ -745,11 +725,13 @@
BonoboObject *object = BONOBO_OBJECT (g_object);
BonoboAggregateObject *ao;
-#ifdef BONOBO_OBJECT_DEBUG
- g_warning ("bonobo_object_instance init '%s' '%s' -> %p",
- G_OBJECT_TYPE_NAME (g_object),
- G_OBJECT_CLASS_NAME (klass), object);
-#endif
+ if(_bonobo_debug_flags & BONOBO_DEBUG_OBJECT) {
+ bonobo_debug_print ("object",
+ "bonobo_object_instance init '%s' '%s' -> %p",
+ G_OBJECT_TYPE_NAME (g_object),
+ G_OBJECT_CLASS_NAME (klass), object);
+ }
+
/* Some simple debugging - count aggregate allocate */
LINC_MUTEX_LOCK (bonobo_total_aggregates_lock);
bonobo_total_aggregates++;
@@ -776,8 +758,7 @@
bonobo_object_finalize_servant: is invoked */
g_object_ref (g_object);
-#ifdef BONOBO_REF_HOOKS
- {
+ if(_bonobo_debug_flags & BONOBO_DEBUG_REFS) {
bonobo_debug_print ("create", "[%p]:[%p]:%s to %d", object, ao,
g_type_name (G_TYPE_FROM_CLASS (klass)),
ao->ref_count);
@@ -785,7 +766,6 @@
g_assert (g_hash_table_lookup (living_ao_ht, ao) == NULL);
g_hash_table_insert (living_ao_ht, ao, ao);
}
-#endif
do_corba_setup (object, BONOBO_OBJECT_CLASS (klass));
}
@@ -813,18 +793,18 @@
(GInstanceInitFunc) bonobo_object_instance_init
};
+ bonobo_debug_init();
+
type = g_type_register_static (G_TYPE_OBJECT, "BonoboObject",
&info, 0);
-#ifdef BONOBO_REF_HOOKS
- living_ao_ht = g_hash_table_new (NULL, NULL);
-#endif
+ if(_bonobo_debug_flags & BONOBO_DEBUG_REFS)
+ living_ao_ht = g_hash_table_new (NULL, NULL);
}
return type;
}
-#ifdef BONOBO_REF_HOOKS
static void
bonobo_ao_debug_foreach (gpointer key, gpointer value, gpointer user_data)
{
@@ -860,27 +840,26 @@
descr->fn, descr->line);
}
}
-#endif
int
bonobo_object_shutdown (void)
{
-#ifdef BONOBO_REF_HOOKS
-
- bonobo_debug_print ("shutdown-start",
- "-------------------------------------------------");
-
- if (living_ao_ht)
- g_hash_table_foreach (living_ao_ht,
- bonobo_ao_debug_foreach, NULL);
-
- bonobo_debug_print ("living-objects",
- "living bonobo objects count = %d",
- g_hash_table_size (living_ao_ht));
+ if(_bonobo_debug_flags & BONOBO_DEBUG_REFS) {
+ bonobo_debug_print ("shutdown-start",
+ "-------------------------------------------------");
+
+ if (living_ao_ht)
+ g_hash_table_foreach (living_ao_ht,
+ bonobo_ao_debug_foreach, NULL);
+
+ bonobo_debug_print ("living-objects",
+ "living bonobo objects count = %d",
+ g_hash_table_size (living_ao_ht));
+
+ bonobo_debug_print ("shutdown-end",
+ "-------------------------------------------------");
+ }
- bonobo_debug_print ("shutdown-end",
- "-------------------------------------------------");
-#endif
if (bonobo_total_aggregates > 0) {
g_warning ("Leaked a total of %ld refs to %ld bonobo object(s)",
bonobo_total_aggregate_refs,
@@ -935,62 +914,62 @@
ao->ref_count = ao->ref_count + oldao->ref_count - 1;
bonobo_total_aggregate_refs--;
-#ifdef BONOBO_REF_HOOKS
- bonobo_debug_print ("add_interface",
- "[%p]:[%p]:%s to [%p]:[%p]:%s ref_count=%d",
- object, object->priv->ao,
- G_OBJECT_TYPE_NAME (object),
- newobj, newobj->priv->ao,
- G_OBJECT_TYPE_NAME (newobj),
- ao->ref_count);
-#endif
+ if(_bonobo_debug_flags & BONOBO_DEBUG_REFS) {
+ bonobo_debug_print ("add_interface",
+ "[%p]:[%p]:%s to [%p]:[%p]:%s ref_count=%d",
+ object, object->priv->ao,
+ G_OBJECT_TYPE_NAME (object),
+ newobj, newobj->priv->ao,
+ G_OBJECT_TYPE_NAME (newobj),
+ ao->ref_count);
+ }
/* Merge the two AggregateObject lists */
for (l = oldao->objs; l; l = l->next) {
BonoboObject *new_if = l->data;
-#ifdef BONOBO_AGGREGATE_DEBUG
- GList *i;
- CORBA_Environment ev;
- CORBA_char *new_id;
-
- CORBA_exception_init (&ev);
-
- new_id = ORBit_small_get_type_id (new_if->corba_objref, &ev);
-
- for (i = ao->objs; i; i = i->next) {
- BonoboObject *old_if = i->data;
-
- if (old_if == new_if)
- g_error ("attempting to merge identical "
- "interfaces [%p]", new_if);
- else {
- CORBA_char *old_id;
-
- old_id = ORBit_small_get_type_id (old_if->corba_objref, &ev);
-
- if (!strcmp (new_id, old_id))
- g_error ("Aggregating two BonoboObject that implement "
- "the same interface '%s' [%p]", new_id, new_if);
- CORBA_free (old_id);
+ if(_bonobo_debug_flags & BONOBO_DEBUG_AGGREGATE) {
+ GList *i;
+ CORBA_Environment ev;
+ CORBA_char *new_id;
+
+ CORBA_exception_init (&ev);
+
+ new_id = ORBit_small_get_type_id (new_if->corba_objref, &ev);
+
+ for (i = ao->objs; i; i = i->next) {
+ BonoboObject *old_if = i->data;
+
+ if (old_if == new_if)
+ g_error ("attempting to merge identical "
+ "interfaces [%p]", new_if);
+ else {
+ CORBA_char *old_id;
+
+ old_id = ORBit_small_get_type_id (old_if->corba_objref, &ev);
+
+ if (!strcmp (new_id, old_id))
+ g_error ("Aggregating two BonoboObject that implement "
+ "the same interface '%s' [%p]", new_id, new_if);
+ CORBA_free (old_id);
+ }
}
+
+ CORBA_free (new_id);
+ CORBA_exception_free (&ev);
}
- CORBA_free (new_id);
- CORBA_exception_free (&ev);
-#endif
-
ao->objs = g_list_prepend (ao->objs, new_if);
new_if->priv->ao = ao;
}
g_assert (newobj->priv->ao == ao);
-#ifdef BONOBO_REF_HOOKS
- g_assert (g_hash_table_lookup (living_ao_ht, oldao) == oldao);
- g_hash_table_remove (living_ao_ht, oldao);
- ao->refs = g_list_concat (ao->refs, oldao->refs);
-#endif
+ if(_bonobo_debug_flags & BONOBO_DEBUG_REFS) {
+ g_assert (g_hash_table_lookup (living_ao_ht, oldao) == oldao);
+ g_hash_table_remove (living_ao_ht, oldao);
+ ao->refs = g_list_concat (ao->refs, oldao->refs);
+ }
g_list_free (oldao->objs);
g_free (oldao);
@@ -1321,10 +1300,10 @@
return FALSE;
}
-#ifdef BONOBO_OBJECT_DEBUG
- g_warning ("We are at depth %d with type '%s'",
- depth, g_type_name (type));
-#endif
+ if(_bonobo_debug_flags & BONOBO_DEBUG_OBJECT) {
+ bonobo_debug_print ("object", "We are at depth %d with type '%s'",
+ depth, g_type_name (type));
+ }
/* Setup the Unknown epv */
bonobo_object_epv_init (&klass->epv);
Index: bonobo/bonobo-running-context.c
===================================================================
RCS file: /cvs/gnome/libbonobo/bonobo/bonobo-running-context.c,v
retrieving revision 1.26
diff -u -r1.26 bonobo-running-context.c
--- bonobo/bonobo-running-context.c 7 Jan 2002 17:26:26 -0000 1.26
+++ bonobo/bonobo-running-context.c 13 May 2002 21:34:23 -0000
@@ -19,22 +19,14 @@
#include <bonobo/bonobo-running-context.h>
#include <bonobo/bonobo-shutdown.h>
#include <bonobo/bonobo-main.h>
+#include <bonobo/bonobo-debug.h>
#define PARENT_TYPE BONOBO_TYPE_OBJECT
-static BonoboObjectClass *bonobo_running_context_parent_class = NULL;
-
-#ifdef BONOBO_OBJECT_DEBUG
-# define BONOBO_RUNNING_HOOKS
-#endif
+/* you may debug by adding item "running" to BONOBO_DEBUG_FLAGS
+ environment variable. */
-/*
- * NB. for a quicker debugging experience simply
- * #define BONOBO_RUNNING_HOOKS
- */
-#if 0
-# define BONOBO_RUNNING_HOOKS
-#endif
+static BonoboObjectClass *bonobo_running_context_parent_class = NULL;
typedef struct {
gboolean emitted_last_unref;
@@ -59,21 +51,6 @@
g_free (name);
}
-#ifdef BONOBO_RUNNING_HOOKS
-static void
-bonobo_debug_print (char *name, char *fmt, ...)
-{
- va_list args;
-
- va_start (args, fmt);
-
- printf ("[%06d]:%-15s ", getpid (), name);
- vprintf (fmt, args);
- printf ("\n");
-
- va_end (args);
-}
-
static void
bonobo_ri_debug_foreach (gpointer key, gpointer value, gpointer user_data)
{
@@ -82,7 +59,6 @@
bonobo_debug_print ("", "[%p]:CORBA_Object still running", o);
}
-#endif
void
bonobo_running_context_shutdown (void)
@@ -91,17 +67,17 @@
BonoboRunningInfo *ri = bonobo_running_info;
-#ifdef BONOBO_RUNNING_HOOKS
- bonobo_debug_print ("rinfo-start",
- "-------------------------------------------------");
-
- bonobo_debug_print ("running-objects", "%d running objects",
- g_hash_table_size (ri->objects));
- g_hash_table_foreach (ri->objects,
- bonobo_ri_debug_foreach, NULL);
- bonobo_debug_print ("rinfo-end",
- "-------------------------------------------------");
-#endif
+ if(_bonobo_debug_flags & BONOBO_DEBUG_RUNNING) {
+ bonobo_debug_print ("rinfo-start",
+ "-------------------------------------------------");
+
+ bonobo_debug_print ("running-objects", "%d running objects",
+ g_hash_table_size (ri->objects));
+ g_hash_table_foreach (ri->objects,
+ bonobo_ri_debug_foreach, NULL);
+ bonobo_debug_print ("rinfo-end",
+ "-------------------------------------------------");
+ }
if (ri->objects)
g_hash_table_destroy (ri->objects);
ri->objects = NULL;
@@ -168,13 +144,13 @@
void
bonobo_running_context_add_object (CORBA_Object object)
{
-#ifdef BONOBO_RUNNING_HOOKS
- bonobo_running_context_trace_objects (object, "local", 0, 0);
-#else
- BonoboRunningInfo *ri = get_running_info (TRUE);
+ if(_bonobo_debug_flags & BONOBO_DEBUG_RUNNING)
+ bonobo_running_context_trace_objects (object, "local", 0, 0);
+ else {
+ BonoboRunningInfo *ri = get_running_info (TRUE);
- g_hash_table_insert (ri->objects, object, object);
-#endif
+ g_hash_table_insert (ri->objects, object, object);
+ }
}
#endif
@@ -183,17 +159,17 @@
void
bonobo_running_context_remove_object (CORBA_Object object)
{
-#ifdef BONOBO_RUNNING_HOOKS
- bonobo_running_context_trace_objects (object, "local", 0, 1);
-#else
- BonoboRunningInfo *ri = get_running_info (FALSE);
+ if(_bonobo_debug_flags & BONOBO_DEBUG_RUNNING)
+ bonobo_running_context_trace_objects (object, "local", 0, 1);
+ else {
+ BonoboRunningInfo *ri = get_running_info (FALSE);
- if (ri) {
- g_hash_table_remove (ri->objects, object);
+ if (ri) {
+ g_hash_table_remove (ri->objects, object);
- check_empty ();
+ check_empty ();
+ }
}
-#endif
}
#endif
@@ -201,15 +177,15 @@
void
bonobo_running_context_ignore_object (CORBA_Object object)
{
-#ifdef BONOBO_RUNNING_HOOKS
- bonobo_running_context_trace_objects (object, "local", 0, 2);
-#else
- BonoboRunningInfo *ri = get_running_info (FALSE);
+ if(_bonobo_debug_flags & BONOBO_DEBUG_RUNNING)
+ bonobo_running_context_trace_objects (object, "local", 0, 2);
+ else {
+ BonoboRunningInfo *ri = get_running_info (FALSE);
- if (ri) {
- g_hash_table_remove (ri->objects, object);
+ if (ri) {
+ g_hash_table_remove (ri->objects, object);
+ }
}
-#endif
}
#endif
@@ -220,13 +196,12 @@
int mode)
{
BonoboRunningInfo *ri = get_running_info (mode == 0);
-#ifdef BONOBO_RUNNING_HOOKS
- char *cmode[] = {
+ static char *cmode[] = {
"add_object",
"remove_object",
"ignore_object"
};
-#endif
+
if (ri) {
switch (mode) {
case 0:
@@ -241,11 +216,11 @@
g_hash_table_remove (ri->objects, object);
break;
}
-#ifdef BONOBO_RUNNING_HOOKS
- bonobo_debug_print (cmode [mode],
- "[%p]:CORBA_Object %d running objects at %s:%d",
- object, g_hash_table_size (ri->objects), fn, line);
-#endif
+
+ if(_bonobo_debug_flags & BONOBO_DEBUG_RUNNING)
+ bonobo_debug_print (cmode [mode],
+ "[%p]:CORBA_Object %d running objects at %s:%d",
+ object, g_hash_table_size (ri->objects), fn, line);
}
}
Index: doc/refcounting.txt
===================================================================
RCS file: /cvs/gnome/libbonobo/doc/refcounting.txt,v
retrieving revision 1.7
diff -u -r1.7 refcounting.txt
--- doc/refcounting.txt 8 Dec 2001 07:24:18 -0000 1.7
+++ doc/refcounting.txt 13 May 2002 21:34:25 -0000
@@ -47,16 +47,14 @@
* Reference leaks
Catching reference leaks is evily difficult. The first approach is to
-re-build bonobo with BONOBO_OBJECT_DEBUG defined in bonobo-object.h.
-This combined with a call to bonobo_shutdown () before exiting your
-program should provide a dump of all object references floating in
-your code. Having re-build bonobo you will need to re-build your
-application, otherwise you will get link errors moaning about not
-being able to find 'bonobo_object_ref / unref'.
-
-A simpler but less verbose way to get ref count debugging without
-re-compiling everything is to simply define BONOBO_REF_HOOKS at the
-top of bonobo-object.c
+set environment variable BONOBO_DEBUG_FLAGS to a colon separated list
+of a subset of {object,running,aggregate,lifecycle,refs}. This will
+enable debugging output in certain parts of libbonobo. The output will
+be written to stdout or, alternatively, if you set BONOBO_DEBUG_DIR to
+a directory path, to a file named "bonobo-debug-<pid>" in that
+directory. This combined with a call to bonobo_shutdown () before
+exiting your program should provide a dump of all object references
+floating in your code.
Another good way of catching leaks, having guessed which object is not
getting freed is to fire up container and component in gdb, break in
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/libbonobo/ChangeLog,v
retrieving revision 1.316
diff -u -r1.316 ChangeLog
--- ChangeLog 10 May 2002 22:48:58 -0000 1.316
+++ ChangeLog 13 May 2002 21:34:35 -0000
@@ -1,3 +1,14 @@
+2002-05-13 Jaka Mocnik <jaka gnu org>
+
+ * bonobo/bonobo-debug.[ch]: debugging print function and parsing of
+ environment variables BONOBO_DEBUG_FLAGS and BONOBO_DEBUG_DIR in
+ order to determine the desired debugging output.
+ * bonobo/Makefile.am: compile the new source file.
+ * bonobo/bonobo-object.c, bonobo/bonobo-running-context.c:
+ instead of conditionally compiling the debugging code, compile
+ it always, but only execute it if the appropriate debugging flags
+ are set.
+
2002-05-10 Pablo Saratxaga <pablo mandrakesoft com>
* configure.in: Added Vietnamese (vi) to ALL_LINGUAS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]