s/glib_trap_/g_trap_/. add comments on g_trap_instance_signals,

Sun Feb  4 07:38:32 2001  Tim Janik  <timj@gtk.org>

        * docs/debugging.txt: s/glib_trap_/g_trap_/. add comments on
        g_trap_instance_signals, g_trace_instance_signals and
        GRUNTIME_DEBUG.

        * gmem.c: s/glib_trap_/g_trap_/.

Sun Feb  4 07:30:53 2001  Tim Janik  <timj@gtk.org>

        * gtype.[hc]: changed g_type_init() to take debugging flags
        initially, a combination of G_TYPE_DEBUG_OBJECTS and
        G_TYPE_DEBUG_SIGNALS. using the G_TYPE_ prefix is a bit odd
        here, but basically g_type_int() serves as initialization
        fucntion for all of GType, GObject, GSignal, so what the heck.

        * gobject.c: special case debugging code properly.
        changed glib_trap_object_ref to g_trap_object_ref.

        * gsignal.c: add signal emission debugging abilities, along with
        a new trap object g_trap_instance_signals.
This commit is contained in:
Tim Janik 2001-02-04 07:03:52 +00:00 committed by Tim Janik
parent b6fef45d5a
commit 22357542e9
19 changed files with 209 additions and 65 deletions

View File

@ -1,3 +1,11 @@
Sun Feb 4 07:38:32 2001 Tim Janik <timj@gtk.org>
* docs/debugging.txt: s/glib_trap_/g_trap_/. add comments on
g_trap_instance_signals, g_trace_instance_signals and
GRUNTIME_DEBUG.
* gmem.c: s/glib_trap_/g_trap_/.
2001-02-04 Tor Lillqvist <tml@iki.fi>
* tests/Makefile.am (thread_LDADD): Change order of libs,

View File

@ -1,3 +1,11 @@
Sun Feb 4 07:38:32 2001 Tim Janik <timj@gtk.org>
* docs/debugging.txt: s/glib_trap_/g_trap_/. add comments on
g_trap_instance_signals, g_trace_instance_signals and
GRUNTIME_DEBUG.
* gmem.c: s/glib_trap_/g_trap_/.
2001-02-04 Tor Lillqvist <tml@iki.fi>
* tests/Makefile.am (thread_LDADD): Change order of libs,

View File

@ -1,3 +1,11 @@
Sun Feb 4 07:38:32 2001 Tim Janik <timj@gtk.org>
* docs/debugging.txt: s/glib_trap_/g_trap_/. add comments on
g_trap_instance_signals, g_trace_instance_signals and
GRUNTIME_DEBUG.
* gmem.c: s/glib_trap_/g_trap_/.
2001-02-04 Tor Lillqvist <tml@iki.fi>
* tests/Makefile.am (thread_LDADD): Change order of libs,

View File

@ -1,3 +1,11 @@
Sun Feb 4 07:38:32 2001 Tim Janik <timj@gtk.org>
* docs/debugging.txt: s/glib_trap_/g_trap_/. add comments on
g_trap_instance_signals, g_trace_instance_signals and
GRUNTIME_DEBUG.
* gmem.c: s/glib_trap_/g_trap_/.
2001-02-04 Tor Lillqvist <tml@iki.fi>
* tests/Makefile.am (thread_LDADD): Change order of libs,

View File

@ -1,3 +1,11 @@
Sun Feb 4 07:38:32 2001 Tim Janik <timj@gtk.org>
* docs/debugging.txt: s/glib_trap_/g_trap_/. add comments on
g_trap_instance_signals, g_trace_instance_signals and
GRUNTIME_DEBUG.
* gmem.c: s/glib_trap_/g_trap_/.
2001-02-04 Tor Lillqvist <tml@iki.fi>
* tests/Makefile.am (thread_LDADD): Change order of libs,

View File

@ -1,3 +1,11 @@
Sun Feb 4 07:38:32 2001 Tim Janik <timj@gtk.org>
* docs/debugging.txt: s/glib_trap_/g_trap_/. add comments on
g_trap_instance_signals, g_trace_instance_signals and
GRUNTIME_DEBUG.
* gmem.c: s/glib_trap_/g_trap_/.
2001-02-04 Tor Lillqvist <tml@iki.fi>
* tests/Makefile.am (thread_LDADD): Change order of libs,

View File

@ -1,3 +1,11 @@
Sun Feb 4 07:38:32 2001 Tim Janik <timj@gtk.org>
* docs/debugging.txt: s/glib_trap_/g_trap_/. add comments on
g_trap_instance_signals, g_trace_instance_signals and
GRUNTIME_DEBUG.
* gmem.c: s/glib_trap_/g_trap_/.
2001-02-04 Tor Lillqvist <tml@iki.fi>
* tests/Makefile.am (thread_LDADD): Change order of libs,

View File

@ -1,3 +1,11 @@
Sun Feb 4 07:38:32 2001 Tim Janik <timj@gtk.org>
* docs/debugging.txt: s/glib_trap_/g_trap_/. add comments on
g_trap_instance_signals, g_trace_instance_signals and
GRUNTIME_DEBUG.
* gmem.c: s/glib_trap_/g_trap_/.
2001-02-04 Tor Lillqvist <tml@iki.fi>
* tests/Makefile.am (thread_LDADD): Change order of libs,

View File

@ -1,7 +1,6 @@
G_BREAKPOINT () traps for the debugger
======================================
Traps (G_BREAKPOINT) and traces for the debuging
================================================
Some code portions contain trap variables that can be set during
debugging time if G_ENABLE_DEBUG has been defined upon compilation
@ -11,18 +10,32 @@ Such traps lead to immediate code halts to examine the current
program state and backtrace.
Currently, the following trap variables exist:
static volatile gulong glib_trap_free_size;
static volatile gulong glib_trap_realloc_size;
static volatile gulong glib_trap_malloc_size;
static volatile gulong g_trap_free_size;
static volatile gulong g_trap_realloc_size;
static volatile gulong g_trap_malloc_size;
If set to a size > 0, g_free(), g_realloc() and g_malloc()
respectively, will be intercepted if the size matches the
size of the corresponding memory block to free/reallocate/allocate.
This will only work with g_mem_set_vtable (glib_mem_profiler_table)
upon startup though, because memory profiling is required to match
on the memory block sizes.
static volatile GObject *glib_trap_object_ref;
static volatile GObject *g_trap_object_ref;
If set to a valid object pointer, ref/unref will be intercepted
with G_BREAKPOINT ();
static volatile gpointer *g_trap_instance_signals;
static volatile gpointer *g_trace_instance_signals;
If set to a valid instance pointer, debugging messages
will be spewed about emissions of signals on this instance.
For g_trap_instance_signals matches, the emissions will
also be intercepted with G_BREAKPOINT ();
Environment variables for debugging
===================================
When G_ENABLE_DEBUG was defined upon compilation, GRuntime supports
an environment variable GRUNTIME_DEBUG that can be set to a
combination of the flags passed in to g_type_init() (currently
"objects" and "signals") to trigger debugging messages about
object bookkeeping and signal emissions during runtime.
2000/12/28 Tim Janik
2000/02/04 Tim Janik

View File

@ -16,6 +16,12 @@
@param_id:
@pspec:
<!-- ##### SECTION ./tmpl/gtypemodule.sgml.sgml:See_Also ##### -->
<para>
</para>
<!-- ##### FUNCTION g_param_spec_hash_table_insert ##### -->
<para>
@ -25,12 +31,6 @@
@pspec:
@owner_type:
<!-- ##### SECTION ./tmpl/gtypemodule.sgml.sgml:See_Also ##### -->
<para>
</para>
<!-- ##### MACRO G_IS_PARAM_VALUE ##### -->
<para>
@ -84,6 +84,12 @@
@pspec:
@trailer:
<!-- ##### SECTION ./tmpl/gtypemodule.sgml.sgml:Long_Description ##### -->
<para>
</para>
<!-- ##### ENUM GSignalType ##### -->
<para>
@ -96,12 +102,6 @@
@G_SIGNAL_ACTION:
@G_SIGNAL_NO_HOOKS:
<!-- ##### SECTION ./tmpl/gtypemodule.sgml.sgml:Long_Description ##### -->
<para>
</para>
<!-- ##### FUNCTION g_signal_type_closure_new ##### -->
<para>

View File

@ -398,6 +398,7 @@ the type system and assorted other code portions (such as the various fundamenta
type implementations or the signal system).
</para>
@debug_flags:
<!-- ##### FUNCTION g_type_name ##### -->

View File

@ -268,9 +268,9 @@ static gulong profile_frees = 0;
static gulong profile_mc_frees = 0;
static GMutex *g_profile_mutex = NULL;
#ifdef G_ENABLE_DEBUG
static volatile gulong glib_trap_free_size = 0;
static volatile gulong glib_trap_realloc_size = 0;
static volatile gulong glib_trap_malloc_size = 0;
static volatile gulong g_trap_free_size = 0;
static volatile gulong g_trap_realloc_size = 0;
static volatile gulong g_trap_malloc_size = 0;
#endif /* G_ENABLE_DEBUG */
#define PROFILE_TABLE(f1,f2,f3) ( ( ((f3) << 2) | ((f2) << 1) | (f1) ) * (MEM_PROFILE_TABLE_SIZE + 1))
@ -404,7 +404,7 @@ profiler_try_malloc (gsize n_bytes)
gulong *p;
#ifdef G_ENABLE_DEBUG
if (glib_trap_malloc_size == n_bytes)
if (g_trap_malloc_size == n_bytes)
G_BREAKPOINT ();
#endif /* G_ENABLE_DEBUG */
@ -442,7 +442,7 @@ profiler_calloc (gsize n_blocks,
gulong *p;
#ifdef G_ENABLE_DEBUG
if (glib_trap_malloc_size == l)
if (g_trap_malloc_size == l)
G_BREAKPOINT ();
#endif /* G_ENABLE_DEBUG */
@ -480,7 +480,7 @@ profiler_free (gpointer mem)
else
{
#ifdef G_ENABLE_DEBUG
if (glib_trap_free_size == p[1])
if (g_trap_free_size == p[1])
G_BREAKPOINT ();
#endif /* G_ENABLE_DEBUG */
@ -506,7 +506,7 @@ profiler_try_realloc (gpointer mem,
p -= 2;
#ifdef G_ENABLE_DEBUG
if (glib_trap_realloc_size == n_bytes)
if (g_trap_realloc_size == n_bytes)
G_BREAKPOINT ();
#endif /* G_ENABLE_DEBUG */

14
gmem.c
View File

@ -268,9 +268,9 @@ static gulong profile_frees = 0;
static gulong profile_mc_frees = 0;
static GMutex *g_profile_mutex = NULL;
#ifdef G_ENABLE_DEBUG
static volatile gulong glib_trap_free_size = 0;
static volatile gulong glib_trap_realloc_size = 0;
static volatile gulong glib_trap_malloc_size = 0;
static volatile gulong g_trap_free_size = 0;
static volatile gulong g_trap_realloc_size = 0;
static volatile gulong g_trap_malloc_size = 0;
#endif /* G_ENABLE_DEBUG */
#define PROFILE_TABLE(f1,f2,f3) ( ( ((f3) << 2) | ((f2) << 1) | (f1) ) * (MEM_PROFILE_TABLE_SIZE + 1))
@ -404,7 +404,7 @@ profiler_try_malloc (gsize n_bytes)
gulong *p;
#ifdef G_ENABLE_DEBUG
if (glib_trap_malloc_size == n_bytes)
if (g_trap_malloc_size == n_bytes)
G_BREAKPOINT ();
#endif /* G_ENABLE_DEBUG */
@ -442,7 +442,7 @@ profiler_calloc (gsize n_blocks,
gulong *p;
#ifdef G_ENABLE_DEBUG
if (glib_trap_malloc_size == l)
if (g_trap_malloc_size == l)
G_BREAKPOINT ();
#endif /* G_ENABLE_DEBUG */
@ -480,7 +480,7 @@ profiler_free (gpointer mem)
else
{
#ifdef G_ENABLE_DEBUG
if (glib_trap_free_size == p[1])
if (g_trap_free_size == p[1])
G_BREAKPOINT ();
#endif /* G_ENABLE_DEBUG */
@ -506,7 +506,7 @@ profiler_try_realloc (gpointer mem,
p -= 2;
#ifdef G_ENABLE_DEBUG
if (glib_trap_realloc_size == n_bytes)
if (g_trap_realloc_size == n_bytes)
G_BREAKPOINT ();
#endif /* G_ENABLE_DEBUG */

View File

@ -1,3 +1,17 @@
Sun Feb 4 07:30:53 2001 Tim Janik <timj@gtk.org>
* gtype.[hc]: changed g_type_init() to take debugging flags
initially, a combination of G_TYPE_DEBUG_OBJECTS and
G_TYPE_DEBUG_SIGNALS. using the G_TYPE_ prefix is a bit odd
here, but basically g_type_int() serves as initialization
fucntion for all of GType, GObject, GSignal, so what the heck.
* gobject.c: special case debugging code properly.
changed glib_trap_object_ref to g_trap_object_ref.
* gsignal.c: add signal emission debugging abilities, along with
a new trap object g_trap_instance_signals.
2001-02-04 Tor Lillqvist <tml@iki.fi>
* Makefile.am (progs_LDADD): Change order of libs to libgobject

View File

@ -126,7 +126,7 @@ main (gint argc,
f_out = stdout;
g_type_init ();
g_type_init (0);
root = G_TYPE_OBJECT;

View File

@ -138,15 +138,10 @@ static gulong gobject_signals[LAST_SIGNAL] = { 0, };
/* --- functions --- */
/* We need an actual method for handling debug keys in GLib.
* For now, we'll simply use, as a method
* 'extern gboolean glib_debug_objects'
*/
gboolean glib_debug_objects = FALSE;
#ifdef G_ENABLE_DEBUG
#define IF_DEBUG(debug_type) if (_g_type_debug_flags & G_TYPE_DEBUG_ ## debug_type)
G_LOCK_DEFINE_STATIC (debug_objects);
static volatile GObject *glib_trap_object_ref = NULL;
static volatile GObject *g_trap_object_ref = NULL;
static guint debug_objects_count = 0;
static GHashTable *debug_objects_ht = NULL;
static void
@ -155,7 +150,7 @@ debug_objects_foreach (gpointer key,
gpointer user_data)
{
GObject *object = value;
g_message ("[%p] stale %s\tref_count=%u",
object,
G_OBJECT_TYPE_NAME (object),
@ -164,18 +159,18 @@ debug_objects_foreach (gpointer key,
static void
debug_objects_atexit (void)
{
G_LOCK (debug_objects);
if (glib_debug_objects)
IF_DEBUG (OBJECTS)
{
G_LOCK (debug_objects);
if (debug_objects_ht)
{
g_message ("stale GObjects: %u", debug_objects_count);
g_hash_table_foreach (debug_objects_ht, debug_objects_foreach, NULL);
}
G_UNLOCK (debug_objects);
}
G_UNLOCK (debug_objects);
}
#endif /* G_ENABLE_DEBUG */
#endif /* G_ENABLE_DEBUG */
void
g_object_type_init (void) /* sync with gtype.c */
@ -218,7 +213,8 @@ g_object_type_init (void) /* sync with gtype.c */
g_assert (type == G_TYPE_OBJECT);
#ifdef G_ENABLE_DEBUG
g_atexit (debug_objects_atexit);
IF_DEBUG (OBJECTS)
g_atexit (debug_objects_atexit);
#endif /* G_ENABLE_DEBUG */
}
@ -439,17 +435,17 @@ g_object_init (GObject *object)
/* freeze object's notification queue, g_object_new_valist() takes care of that */
object_freeze_notifies (object);
#ifdef G_ENABLE_DEBUG
G_LOCK (debug_objects);
if (glib_debug_objects)
IF_DEBUG (OBJECTS)
{
G_LOCK (debug_objects);
if (!debug_objects_ht)
debug_objects_ht = g_hash_table_new (g_direct_hash, NULL);
debug_objects_count++;
g_hash_table_insert (debug_objects_ht, object, object);
G_UNLOCK (debug_objects);
}
G_UNLOCK (debug_objects);
#endif /* G_ENABLE_DEBUG */
}
@ -522,7 +518,7 @@ g_object_last_unref (GObject *object)
G_OBJECT_GET_CLASS (object)->shutdown (object);
#ifdef G_ENABLE_DEBUG
if (glib_trap_object_ref == object)
if (g_trap_object_ref == object)
G_BREAKPOINT ();
#endif /* G_ENABLE_DEBUG */
@ -532,10 +528,13 @@ g_object_last_unref (GObject *object)
{
G_OBJECT_GET_CLASS (object)->finalize (object);
#ifdef G_ENABLE_DEBUG
G_LOCK (debug_objects);
if (glib_debug_objects && debug_objects_ht)
g_assert (g_hash_table_lookup (debug_objects_ht, object) == NULL);
G_UNLOCK (debug_objects);
IF_DEBUG (OBJECTS)
{
G_LOCK (debug_objects);
if (debug_objects_ht)
g_assert (g_hash_table_lookup (debug_objects_ht, object) == NULL);
G_UNLOCK (debug_objects);
}
#endif /* G_ENABLE_DEBUG */
g_type_free_instance ((GTypeInstance*) object);
}
@ -557,15 +556,14 @@ g_object_finalize (GObject *object)
g_datalist_clear (&object->qdata);
#ifdef G_ENABLE_DEBUG
G_LOCK (debug_objects);
if (glib_debug_objects)
IF_DEBUG (OBJECTS)
{
G_LOCK (debug_objects);
g_assert (g_hash_table_lookup (debug_objects_ht, object) == object);
g_hash_table_remove (debug_objects_ht, object);
debug_objects_count--;
G_UNLOCK (debug_objects);
}
G_UNLOCK (debug_objects);
#endif /* G_ENABLE_DEBUG */
}
@ -1243,7 +1241,7 @@ g_object_ref (gpointer _object)
g_return_val_if_fail (object->ref_count > 0, NULL);
#ifdef G_ENABLE_DEBUG
if (glib_trap_object_ref == object)
if (g_trap_object_ref == object)
G_BREAKPOINT ();
#endif /* G_ENABLE_DEBUG */
@ -1261,7 +1259,7 @@ g_object_unref (gpointer _object)
g_return_if_fail (object->ref_count > 0);
#ifdef G_ENABLE_DEBUG
if (glib_trap_object_ref == object)
if (g_trap_object_ref == object)
G_BREAKPOINT ();
#endif /* G_ENABLE_DEBUG */

View File

@ -38,6 +38,11 @@
#define EMISSION_PRE_ALLOC (16)
#define REPORT_BUG "please report occourance circumstances to gtk-devel-list@gnome.org"
#ifdef G_ENABLE_DEBUG
#define IF_DEBUG(debug_type, cond) if ((_g_type_debug_flags & G_TYPE_DEBUG_ ## debug_type) || cond)
static volatile gpointer *g_trace_instance_signals = NULL;
static volatile gpointer *g_trap_instance_signals = NULL;
#endif /* G_ENABLE_DEBUG */
/* --- generic allocation --- */
@ -1743,6 +1748,18 @@ signal_emit_R (SignalNode *node,
guint signal_id = node->signal_id;
gboolean return_value_altered = FALSE;
#ifdef G_ENABLE_DEBUG
IF_DEBUG (SIGNALS, g_trace_instance_signals == instance || g_trap_instance_signals == instance)
{
g_message ("%s::%s(%u) emitted (instance=%p signal-node=%p)\n",
g_type_name (G_TYPE_FROM_INSTANCE (instance)),
node->name, detail,
instance, node);
if (g_trap_instance_signals == instance)
G_BREAKPOINT ();
}
#endif /* G_ENABLE_DEBUG */
if (node->flags & G_SIGNAL_NO_RECURSE)
{
Emission *emission = emission_find (g_restart_emissions, signal_id, detail, instance);

View File

@ -69,6 +69,14 @@ static GStaticRWLock type_rw_lock = G_STATIC_RW_LOCK_INIT;
else \
g_error ("%s()%s`%s'", _fname, _action, _tname); \
}G_STMT_END
#ifdef G_ENABLE_DEBUG
#define DEBUG_CODE(debug_type, code_block) G_STMT_START { \
if (_g_type_debug_flags & G_TYPE_DEBUG_ ## debug_type) \
{ code_block; } \
} G_STMT_END
#else /* !G_ENABLE_DEBUG */
#define DEBUG_CODE(debug_type, code_block) /* code_block */
#endif /* G_ENABLE_DEBUG */
#define TYPE_FUNDAMENTAL_FLAG_MASK (G_TYPE_FLAG_CLASSED | \
G_TYPE_FLAG_INSTANTIATABLE | \
@ -202,6 +210,7 @@ static guint static_n_class_cache_funcs = 0;
static ClassCacheFunc *static_class_cache_funcs = NULL;
static GType static_last_fundamental_id = 0;
static GQuark static_quark_type_flags = 0;
GTypeDebugFlags _g_type_debug_flags = 0;
/* --- externs --- */
@ -2354,10 +2363,11 @@ extern void g_signal_init (void); /* sync with gsignal.c */
/* --- initialization --- */
void
g_type_init (void)
g_type_init (GTypeDebugFlags debug_flags)
{
G_LOCK_DEFINE_STATIC (type_init_lock);
static TypeNode *type0_node = NULL;
gchar *env_string;
GTypeInfo info;
TypeNode *node;
GType type;
@ -2372,6 +2382,22 @@ g_type_init (void)
G_UNLOCK (type_init_lock);
return;
}
/* setup GRuntime wide debugging flags */
_g_type_debug_flags = debug_flags & G_TYPE_DEBUG_MASK;
env_string = g_getenv ("GRUNTIME_DEBUG");
if (env_string != NULL)
{
static GDebugKey debug_keys[] = {
{ "objects", G_TYPE_DEBUG_OBJECTS },
{ "signals", G_TYPE_DEBUG_SIGNALS },
};
_g_type_debug_flags |= g_parse_debug_string (env_string,
debug_keys,
sizeof (debug_keys) / sizeof (debug_keys[0]));
env_string = NULL;
}
/* quarks */
static_quark_type_flags = g_quark_from_static_string ("GTypeFlags");

View File

@ -168,8 +168,17 @@ struct _GTypeInterface
#define G_TYPE_FROM_INTERFACE(g_iface) (((GTypeInterface*) (g_iface))->g_type)
/* debug flags for g_type_init() */
typedef enum /*< skip >*/
{
G_TYPE_DEBUG_OBJECTS = 1 << 0,
G_TYPE_DEBUG_SIGNALS = 1 << 1,
G_TYPE_DEBUG_MASK = 0x03
} GTypeDebugFlags;
/* --- prototypes --- */
void g_type_init (void);
void g_type_init (GTypeDebugFlags debug_flags);
gchar* g_type_name (GType type);
GQuark g_type_qname (GType type);
GType g_type_from_name (const gchar *name);
@ -328,6 +337,7 @@ gboolean g_type_value_is_a (GValue *value,
GTypeValueTable* g_type_value_table_peek (GType type);
/* --- implementation bits --- */
#ifndef G_DISABLE_CAST_CHECKS
# define _G_TYPE_CIC(ip, gt, ct) \
((ct*) g_type_check_instance_cast ((GTypeInstance*) ip, gt))
@ -345,6 +355,7 @@ GTypeValueTable* g_type_value_table_peek (GType type);
#define _G_TYPE_IGC(ip, gt, ct) ((ct*) (((GTypeInstance*) ip)->g_class))
#define _G_TYPE_IGI(ip, gt, ct) ((ct*) g_type_interface_peek (((GTypeInstance*) ip)->g_class, gt))
#define G_TYPE_FLAG_RESERVED_ID_BIT (1 << 30)
extern GTypeDebugFlags _g_type_debug_flags;
#ifdef __cplusplus