a patch for runtime debugging control for libbonobo



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]