[gst-devel] Re: buffer debugging

vishnu at pobox.com vishnu at pobox.com
Sat Sep 22 17:51:01 CEST 2001


On Sat, Sep 22, 2001 at 03:47:54PM -0700, vishnu at pobox.com wrote:
> Here's the idea.  (untested)

Taaz, try this patch.  (tested)

-- 
Victory to the Divine Mother!!
  http://sahajayoga.org
-------------- next part --------------
? alled
? gst/d1
Index: gst/gstbuffer.c
===================================================================
RCS file: /cvsroot/gstreamer/gstreamer/gst/gstbuffer.c,v
retrieving revision 1.36.2.5
diff -u -p -r1.36.2.5 gstbuffer.c
--- gst/gstbuffer.c	2001/09/21 17:31:45	1.36.2.5
+++ gst/gstbuffer.c	2001/09/23 00:05:12
@@ -32,6 +32,10 @@ GType _gst_buffer_type;
 static GMemChunk *_gst_buffer_chunk;
 static GMutex *_gst_buffer_chunk_lock;
 
+// This should be conditional compiled only for debugging.
+static glong _debug_buffer_instance = 0;
+static GSList *_debug_live = 0;
+
 void 
 _gst_buffer_initialize (void) 
 {
@@ -67,12 +71,14 @@ _gst_buffer_initialize (void) 
  * Returns: new buffer
  */
 GstBuffer*
-gst_buffer_new (void) 
+gst_buffer_new_loc (const gchar *file, gint line) 
 {
   GstBuffer *buffer;
 
   g_mutex_lock (_gst_buffer_chunk_lock);
   buffer = g_mem_chunk_alloc (_gst_buffer_chunk);
+  ++_debug_buffer_instance;
+  _debug_live = g_slist_prepend (_debug_live, buffer);
   g_mutex_unlock (_gst_buffer_chunk_lock);
   GST_INFO (GST_CAT_BUFFER,"creating new buffer %p",buffer);
 
@@ -96,6 +102,9 @@ gst_buffer_new (void) 
   buffer->free = NULL;
   buffer->copy = NULL;
   
+  buffer->file = file;
+  buffer->line = line;
+
   return buffer;
 }
 
@@ -108,18 +117,21 @@ gst_buffer_new (void) 
  * Returns: new buffer
  */
 GstBuffer*
-gst_buffer_new_from_pool (GstBufferPool *pool, guint64 location, gint size)
+gst_buffer_new_from_pool (GstBufferPool *pool, guint32 offset, guint32 size)
 {
   GstBuffer *buffer;
 
   g_return_val_if_fail (pool != NULL, NULL);
   g_return_val_if_fail (pool->buffer_new != NULL, NULL);
   
-  buffer = pool->buffer_new (pool, location, size, pool->user_data);
+  buffer = pool->buffer_new (pool, offset, size, pool->user_data);
   buffer->pool = pool;
   buffer->free = pool->buffer_free;
   buffer->copy = pool->buffer_copy;
   
+  GST_INFO (GST_CAT_BUFFER,"creating new buffer %p from pool %p (size %x, offset %x)", 
+		  buffer, pool, size, offset);
+
   return buffer;
 }
 
@@ -134,9 +146,11 @@ gst_buffer_new_from_pool (GstBufferPool 
  * Returns: new buffer
  */
 GstBuffer*
-gst_buffer_create_sub (GstBuffer *parent,
-		       guint32 offset,
-		       guint32 size) 
+gst_buffer_create_sub_loc (const gchar *file,
+			   gint line,
+			   GstBuffer *parent,
+			   guint32 offset,
+			   guint32 size) 
 {
   GstBuffer *buffer;
 
@@ -146,6 +160,8 @@ gst_buffer_create_sub (GstBuffer *parent
 
   g_mutex_lock (_gst_buffer_chunk_lock);
   buffer = g_mem_chunk_alloc (_gst_buffer_chunk);
+  ++_debug_buffer_instance;
+  _debug_live = g_slist_prepend (_debug_live, buffer);
   g_mutex_unlock (_gst_buffer_chunk_lock);
   GST_INFO (GST_CAT_BUFFER,"creating new subbuffer %p from parent %p (size %u, offset %u)", 
 		  buffer, parent, size, offset);
@@ -184,7 +200,10 @@ gst_buffer_create_sub (GstBuffer *parent
   gst_buffer_ref (parent);
 
   buffer->pool = NULL;
-  // return the new subbuffer
+
+  buffer->file = file;
+  buffer->line = line;
+
   return buffer;
 }
 
@@ -201,8 +220,10 @@ gst_buffer_create_sub (GstBuffer *parent
  * Returns: new buffer
  */
 GstBuffer*
-gst_buffer_append (GstBuffer *buffer, 
-		   GstBuffer *append) 
+gst_buffer_append_loc (const gchar *file,
+		       gint line,
+		       GstBuffer *buffer, 
+		       GstBuffer *append) 
 {
   guint size;
   GstBuffer *newbuf;
@@ -226,7 +247,7 @@ gst_buffer_append (GstBuffer *buffer, 
   }
   // the buffer is used, create a new one 
   else {
-    newbuf = gst_buffer_new ();
+    newbuf = gst_buffer_new_loc (file, line);
     newbuf->size = buffer->size+append->size;
     newbuf->data = g_malloc (newbuf->size);
     memcpy (newbuf->data, buffer->data, buffer->size);
@@ -250,7 +271,10 @@ gst_buffer_destroy (GstBuffer *buffer) 
 
   g_return_if_fail (buffer != NULL);
   
-  GST_INFO (GST_CAT_BUFFER,"freeing %sbuffer %p", (buffer->parent?"sub":""),buffer);
+  GST_INFO (GST_CAT_BUFFER, "freeing %sbuffer %p (%ld buffers remain)",
+	    (buffer->parent?"sub":""),
+	    buffer,
+	    _debug_buffer_instance - 1);
   
   // free the data only if there is some, DONTFREE isn't set, and not sub
   if (GST_BUFFER_DATA (buffer) &&
@@ -271,12 +295,30 @@ gst_buffer_destroy (GstBuffer *buffer) 
   g_mutex_free (buffer->lock);
   //g_print("freed mutex\n");
 
+#ifdef GST_DEBUG_ENABLED
+  // make it hard to reuse by mistake
+  memset (buffer, ~0, sizeof (GstBuffer));
+#endif
+
   // remove it entirely from memory
   g_mutex_lock (_gst_buffer_chunk_lock);
   g_mem_chunk_free (_gst_buffer_chunk,buffer);
+  --_debug_buffer_instance;
+  _debug_live = g_slist_delete_link (_debug_live,
+				     g_slist_find (_debug_live, buffer));
   g_mutex_unlock (_gst_buffer_chunk_lock);
 }
 
+void gst_buffer_print_live ()
+{
+  GSList *elem;
+
+  for (elem = _debug_live; elem; elem = elem->next) {
+    GstBuffer *buf = elem->data;
+    g_print ("buffer %p created %s:%d\n", buf, buf->file, buf->line);
+  }
+}
+
 /**
  * gst_buffer_ref:
  * @buffer: the GstBuffer to reference
@@ -288,7 +330,7 @@ gst_buffer_ref (GstBuffer *buffer) 
 {
   g_return_if_fail (buffer != NULL);
 
-  GST_DEBUG (0,"referencing buffer %p\n", buffer);
+  GST_INFO (GST_CAT_BUFFER, "ref buffer %p\n", buffer);
 
 #ifdef HAVE_ATOMIC_H
   //g_return_if_fail(atomic_read(&(buffer->refcount)) > 0);
@@ -302,30 +344,6 @@ gst_buffer_ref (GstBuffer *buffer) 
 }
 
 /**
- * gst_buffer_ref_by_count:
- * @buffer: the GstBuffer to reference
- * @count: a number
- *
- * Increment the refcount of this buffer by the given number.
- */
-void 
-gst_buffer_ref_by_count (GstBuffer *buffer, int count) 
-{
-  g_return_if_fail (buffer != NULL);
-  g_return_if_fail (count > 0);
-
-#ifdef HAVE_ATOMIC_H
-  g_return_if_fail (atomic_read (&(buffer->refcount)) > 0);
-  atomic_add (count, &(buffer->refcount));
-#else
-  g_return_if_fail (buffer->refcount > 0);
-  GST_BUFFER_LOCK (buffer);
-  buffer->refcount += count;
-  GST_BUFFER_UNLOCK (buffer);
-#endif
-}
-
-/**
  * gst_buffer_unref:
  * @buffer: the GstBuffer to unref
  *
@@ -339,7 +357,7 @@ gst_buffer_unref (GstBuffer *buffer) 
 
   g_return_if_fail (buffer != NULL);
 
-  GST_DEBUG (0,"unreferencing buffer %p\n", buffer);
+  GST_INFO (GST_CAT_BUFFER, "unref buffer %p\n", buffer);
 
 #ifdef HAVE_ATOMIC_H
   g_return_if_fail (atomic_read (&(buffer->refcount)) > 0);
@@ -367,12 +385,14 @@ gst_buffer_unref (GstBuffer *buffer) 
  * Returns: new buffer
  */
 GstBuffer *
-gst_buffer_copy (GstBuffer *buffer)
+gst_buffer_copy_loc (const gchar *file,
+		     gint line,
+		     GstBuffer *buffer)
 {
   GstBuffer *newbuf;
 
   // allocate a new buffer
-  newbuf = gst_buffer_new();
+  newbuf = gst_buffer_new_loc (file, line);
 
   // if a copy function exists, use it, else copy the bytes
   if (buffer->copy != NULL) {
@@ -436,7 +456,8 @@ gst_buffer_is_span_fast (GstBuffer *buf1
  */
 // FIXME need to think about CoW and such...
 GstBuffer *
-gst_buffer_span (GstBuffer *buf1, guint32 offset, GstBuffer *buf2, guint32 len)
+gst_buffer_span_loc (const gchar *file, gint line,
+		     GstBuffer *buf1, guint32 offset, GstBuffer *buf2, guint32 len)
 {
   GstBuffer *newbuf;
 
@@ -453,12 +474,13 @@ gst_buffer_span (GstBuffer *buf1, guint3
 //      ((buf1->data + buf1->size) == buf2->data)) {
   if (gst_buffer_is_span_fast(buf1,buf2)) {
     // we simply create a subbuffer of the common parent
-    newbuf =  gst_buffer_create_sub(buf1->parent, buf1->data - (buf1->parent->data) + offset, len);
+    newbuf = gst_buffer_create_sub_loc(file, line,
+				       buf1->parent, buf1->data - (buf1->parent->data) + offset, len);
   }
   else {
     g_print ("slow path taken in buffer_span\n");
     // otherwise we simply have to brute-force copy the buffers
-    newbuf = gst_buffer_new();
+    newbuf = gst_buffer_new_loc (file, line);
 
     // put in new size
     newbuf->size = len;
@@ -496,8 +518,9 @@ gst_buffer_span (GstBuffer *buf1, guint3
  * Returns: new buffer that's the concatenation of the source buffers
  */
 GstBuffer *
-gst_buffer_merge (GstBuffer *buf1, GstBuffer *buf2)
+gst_buffer_merge_loc (const gchar *file, gint line,
+		      GstBuffer *buf1, GstBuffer *buf2)
 {
   // we're just a specific case of the more general gst_buffer_span()
-  return gst_buffer_span(buf1, 0, buf2, buf1->size + buf2->size);
+  return gst_buffer_span_loc (file, line, buf1, 0, buf2, buf1->size + buf2->size);
 }
Index: gst/gstbuffer.h
===================================================================
RCS file: /cvsroot/gstreamer/gstreamer/gst/gstbuffer.h,v
retrieving revision 1.26.4.1
diff -u -p -r1.26.4.1 gstbuffer.h
--- gst/gstbuffer.h	2001/09/11 09:58:16	1.26.4.1
+++ gst/gstbuffer.h	2001/09/23 00:05:12
@@ -119,9 +119,12 @@ struct _GstBuffer {
   guint32 maxsize;
   guint32 offset;
 
+  // where created (debug)
+  const gchar *file;
+  gint line;
+
   /* timestamp */
   gint64 timestamp;
-  /* max age */
   gint64 maxage;
 
   /* subbuffer support, who's my parent? */
@@ -139,29 +142,46 @@ struct _GstBuffer {
 /* initialisation */
 void 		_gst_buffer_initialize		(void);
 /* creating a new buffer from scratch */
-GstBuffer*	gst_buffer_new			(void);
-GstBuffer*	gst_buffer_new_from_pool 	(GstBufferPool *pool, guint64 location, gint size);
+GstBuffer*	gst_buffer_new_loc		(const gchar *file, gint line);
+GstBuffer*	gst_buffer_new_from_pool 	(GstBufferPool *pool, guint32 offset, guint32 size);
 
 /* creating a subbuffer */
-GstBuffer*	gst_buffer_create_sub		(GstBuffer *parent, guint32 offset, guint32 size);
+GstBuffer*	gst_buffer_create_sub_loc	(const gchar *file, gint line,
+						 GstBuffer *parent, guint32 offset, guint32 size);
 
 /* refcounting */
 void 		gst_buffer_ref			(GstBuffer *buffer);
-void 		gst_buffer_ref_by_count		(GstBuffer *buffer, int count);
 void 		gst_buffer_unref		(GstBuffer *buffer);
 
 /* destroying the buffer */
 void 		gst_buffer_destroy		(GstBuffer *buffer);
 
 /* copy buffer */
-GstBuffer*	gst_buffer_copy			(GstBuffer *buffer);
+GstBuffer*	gst_buffer_copy_loc		(const gchar *file, gint line,
+						 GstBuffer *buffer);
 
 /* merge, span, or append two buffers, intelligently */
-GstBuffer*	gst_buffer_merge		(GstBuffer *buf1, GstBuffer *buf2);
-GstBuffer*	gst_buffer_span			(GstBuffer *buf1,guint32 offset,GstBuffer *buf2,guint32 len);
-GstBuffer*	gst_buffer_append		(GstBuffer *buf, GstBuffer *buf2);
+GstBuffer*	gst_buffer_merge_loc		(const gchar *file, gint line,
+						 GstBuffer *buf1, GstBuffer *buf2);
+GstBuffer*	gst_buffer_span_loc		(const gchar *file, gint line,
+						 GstBuffer *buf1,guint32 offset,GstBuffer *buf2,guint32 len);
+GstBuffer*	gst_buffer_append_loc		(const gchar *file, gint line,
+						 GstBuffer *buf, GstBuffer *buf2);
 
 gboolean	gst_buffer_is_span_fast		(GstBuffer *buf1, GstBuffer *buf2);
+
+#define gst_buffer_new() \
+  gst_buffer_new_loc(__FILE__, __LINE__)
+#define gst_buffer_create_sub(parent, offset, size) \
+  gst_buffer_create_sub_loc(__FILE__, __LINE__, parent, offset, size)
+#define gst_buffer_copy(buffer) \
+  gst_buffer_copy_loc(__FILE__, __LINE__, buffer)
+#define gst_buffer_merge(buf1, buf2) \
+  gst_buffer_merge_loc(__FILE__, __LINE__, buf1, buf2)
+#define gst_buffer_span(buf1, offset, buf2, len) \
+  gst_buffer_span_loc(__FILE__, __LINE__, buf1, offset, buf2, len)
+#define gst_buffer_append(buf, buf2) \
+  gst_buffer_append_loc(__FILE__, __LINE__, buf, buf2)
 
 #ifdef __cplusplus
 }
Index: gst/gstbufferpool.c
===================================================================
RCS file: /cvsroot/gstreamer/gstreamer/gst/gstbufferpool.c,v
retrieving revision 1.18
diff -u -p -r1.18 gstbufferpool.c
--- gst/gstbufferpool.c	2001/08/31 16:40:03	1.18
+++ gst/gstbufferpool.c	2001/09/23 00:05:12
@@ -313,7 +313,7 @@ gst_buffer_pool_get_default (guint buffe
   pool = gst_buffer_pool_new();
   gst_buffer_pool_set_buffer_new_function (pool, gst_buffer_pool_default_buffer_new);
   gst_buffer_pool_set_buffer_free_function (pool, gst_buffer_pool_default_buffer_free);
-  gst_buffer_pool_set_buffer_copy_function (pool, gst_buffer_copy);
+  gst_buffer_pool_set_buffer_copy_function (pool, NULL);
   gst_buffer_pool_set_destroy_hook (pool, gst_buffer_pool_default_destroy_hook);
   
   def = g_new0 (GstBufferPoolDefault, 1);


More information about the gstreamer-devel mailing list