From e8395f57a9a4f28f067c6ffaf2f975526f8574eb Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Sun, 2 Feb 2003 19:10:44 +0000 Subject: [PATCH] Add infrastructure to trace memleaks. Original commit message from CVS: Add infrastructure to trace memleaks. --- gst/gsttrace.c | 186 +++++++++++++++++++++++++++++++++++++++++++++++++ gst/gsttrace.h | 60 +++++++++++++++- 2 files changed, 244 insertions(+), 2 deletions(-) diff --git a/gst/gsttrace.c b/gst/gsttrace.c index f0fac78bf7..ec846fab6a 100644 --- a/gst/gsttrace.c +++ b/gst/gsttrace.c @@ -153,3 +153,189 @@ _gst_trace_add_entry (GstTrace * trace, guint32 seq, guint32 data, gchar * msg) gst_trace_flush (trace); } + + +/* global flags */ +static GstAllocTraceFlags _gst_trace_flags = 0; +/* list of registered tracers */ +static GList *_gst_alloc_tracers = NULL; + +/** + * gst_alloc_trace_available: + * + * Check if alloc tracing was commiled into the core + * + * Returns: TRUE if the core was compiled with alloc + * tracing enabled. + */ +gboolean +gst_alloc_trace_available (void) +{ +#ifdef GST_WITH_ALLOC_TRACE + return TRUE; +#else + return FALSE; +#endif +} + +/** + * _gst_alloc_trace_register: + * @name: the name of the new alloc trace object. + * + * Register an get a handle to a GstAllocTrace object that + * can be used to trace memory allocations. + * + * Returns: A handle to a GstAllocTrace. + */ +GstAllocTrace* +_gst_alloc_trace_register (const gchar *name) +{ + GstAllocTrace *trace; + + g_return_val_if_fail (name, NULL); + + trace = g_new0 (GstAllocTrace, 1); + trace->name = g_strdup (name); + trace->live = 0; + trace->mem_live = NULL; + trace->flags = _gst_trace_flags; + + _gst_alloc_tracers = g_list_prepend (_gst_alloc_tracers, trace); + + return trace; +} + +/** + * gst_alloc_trace_list: + * + * Get a list of all registered alloc trace objects. + * + * Returns: a GList of GstAllocTrace objects. + */ +const GList* +gst_alloc_trace_list (void) +{ + return _gst_alloc_tracers; +} + +/** + * gst_alloc_trace_print_all: + * + * Print the status of all registered alloc trace objectes. + */ +void +gst_alloc_trace_print_all (void) +{ + GList *walk = _gst_alloc_tracers; + + while (walk) { + GstAllocTrace *trace = (GstAllocTrace *) walk->data; + + gst_alloc_trace_print (trace); + + walk = g_list_next (walk); + } +} + +/** + * gst_alloc_trace_set_flags_all: + * @flags: the options to enable + * + * Enable the specified options on all registered alloc trace + * objects. + */ +void +gst_alloc_trace_set_flags_all (GstAllocTraceFlags flags) +{ + GList *walk = _gst_alloc_tracers; + + while (walk) { + GstAllocTrace *trace = (GstAllocTrace *) walk->data; + + gst_alloc_trace_set_flags (trace, flags); + + walk = g_list_next (walk); + } + _gst_trace_flags = flags; +} + +/** + * gst_alloc_trace_get: + * @name: the name of the alloc trace object + * + * Get the named alloc trace object. + * + * Returns: a GstAllocTrace with the given name or NULL when + * no alloc tracer was registered with that name. + */ +GstAllocTrace* +gst_alloc_trace_get (const gchar *name) +{ + GList *walk = _gst_alloc_tracers; + + g_return_val_if_fail (name, NULL); + + while (walk) { + GstAllocTrace *trace = (GstAllocTrace *) walk->data; + + if (!strcmp (trace->name, name)) + return trace; + + walk = g_list_next (walk); + } + return NULL; +} + +/** + * gst_alloc_trace_print: + * @trace: the GstAllocTrace to print + * + * Print the status of the given GstAllocTrace. + */ +void +gst_alloc_trace_print (const GstAllocTrace *trace) +{ + GSList *mem_live; + + g_return_if_fail (trace != NULL); + + g_print ("%s: flags %d", trace->name, trace->flags); + + if (trace->flags & GST_ALLOC_TRACE_LIVE) { + g_print (", live %d", trace->live); + } + if (trace->flags & GST_ALLOC_TRACE_MEM_LIVE) { + mem_live = trace->mem_live; + + if (!mem_live) { + g_print (", no live memory"); + } + else { + g_print (", dumping live memory: "); + + while (mem_live) { + g_print ("%p ", mem_live->data); + mem_live = g_slist_next (mem_live); + } + g_print ("\ntotal %d", g_slist_length (trace->mem_live)); + } + } + g_print ("\n"); +} + +/** + * gst_alloc_trace_set_flags: + * @trace: the GstAllocTrace + * @flags: flags to set + * + * Enable the given features on the given GstAllocTrace object. + */ +void +gst_alloc_trace_set_flags (GstAllocTrace *trace, GstAllocTraceFlags flags) +{ + g_return_if_fail (trace != NULL); + + trace->flags = flags; +} + + diff --git a/gst/gsttrace.h b/gst/gsttrace.h index a3b0ad77af..2e0abcbd8b 100644 --- a/gst/gsttrace.h +++ b/gst/gsttrace.h @@ -51,6 +51,8 @@ struct _GstTraceEntry { gchar message[112]; }; + + GstTrace* gst_trace_new (gchar *filename, gint size); void gst_trace_destroy (GstTrace *trace); @@ -66,9 +68,63 @@ void _gst_trace_add_entry (GstTrace *trace, guint32 seq, void gst_trace_read_tsc (gint64 *dst); -#define TRACE_ENABLE -#ifdef TRACE_ENABLE +typedef enum +{ + GST_ALLOC_TRACE_LIVE = (1 << 0), + GST_ALLOC_TRACE_MEM_LIVE = (1 << 1), +} GstAllocTraceFlags; + +typedef struct _GstAllocTrace GstAllocTrace; + +struct _GstAllocTrace { + gchar *name; + gint flags; + + gint live; + GSList *mem_live; +}; + +gboolean gst_alloc_trace_available (void); +const GList* gst_alloc_trace_list (void); +GstAllocTrace* _gst_alloc_trace_register (const gchar *name); + +void gst_alloc_trace_print_all (void); +void gst_alloc_trace_set_flags_all (GstAllocTraceFlags flags); + +GstAllocTrace* gst_alloc_trace_get (const gchar *name); +void gst_alloc_trace_print (const GstAllocTrace *trace); +void gst_alloc_trace_set_flags (GstAllocTrace *trace, GstAllocTraceFlags flags); + + +#ifdef GST_WITH_ALLOC_TRACE +#define gst_alloc_trace_register(name) _gst_alloc_trace_register (name); +#define gst_alloc_trace_new(trace, mem) \ +G_STMT_START { \ + if ((trace)->flags & GST_ALLOC_TRACE_LIVE) \ + (trace)->live++; \ + if ((trace)->flags & GST_ALLOC_TRACE_MEM_LIVE) \ + (trace)->mem_live = \ + g_slist_prepend ((trace)->mem_live, mem); \ +} G_STMT_END + +#define gst_alloc_trace_free(trace, mem) \ +G_STMT_START { \ + if ((trace)->flags & GST_ALLOC_TRACE_LIVE) \ + (trace)->live--; \ + if ((trace)->flags & GST_ALLOC_TRACE_MEM_LIVE) \ + (trace)->mem_live = \ + g_slist_remove ((trace)->mem_live, mem); \ +} G_STMT_END + +#else +#define gst_alloc_trace_register(name) NULL +#define gst_alloc_trace_new(trace, mem) +#define gst_alloc_trace_free(trace, mem) +#endif + + +#ifndef GST_DISABLE_TRACE extern gint _gst_trace_on; #define gst_trace_add_entry(trace,seq,data,msg) \ if (_gst_trace_on) { \