add support for detecting if GStreamer runs inside valgrind.

Original commit message from CVS:
* configure.ac:
* gst/Makefile.am:
* gst/gst_private.h:
* gst/gstinfo.c: (__gst_in_valgrind), (_gst_debug_init):
add support for detecting if GStreamer runs inside valgrind.
requires valgrind (d'oh) and --enable-debug for correct cdetection.
print a big message in valgrind that GStreamer has detected it's
running inside and might now use different code.
* gst/gstmemchunk.c: (populate), (free_area),
(gst_mem_chunk_destroy), (gst_mem_chunk_alloc),
(gst_mem_chunk_free):
flag memchunks for valgrind, so it can detect leaking of chunks.
This allows detecting leaks of GstBuffer and GstEvent correctly
inside valgrind.
This commit is contained in:
Benjamin Otte 2004-04-05 21:42:07 +00:00
parent cce13e8e5c
commit e0ab9b5740
6 changed files with 117 additions and 5 deletions

View file

@ -1,3 +1,20 @@
2004-04-05 Benjamin Otte <otte@gnome.org>
* configure.ac:
* gst/Makefile.am:
* gst/gst_private.h:
* gst/gstinfo.c: (__gst_in_valgrind), (_gst_debug_init):
add support for detecting if GStreamer runs inside valgrind.
requires valgrind (d'oh) and --enable-debug for correct cdetection.
print a big message in valgrind that GStreamer has detected it's
running inside and might now use different code.
* gst/gstmemchunk.c: (populate), (free_area),
(gst_mem_chunk_destroy), (gst_mem_chunk_alloc),
(gst_mem_chunk_free):
flag memchunks for valgrind, so it can detect leaking of chunks.
This allows detecting leaks of GstBuffer and GstEvent correctly
inside valgrind.
2004-04-05 David Schleef <ds@schleef.org>
* gst/gsttrace.h: Fix #ifdef nesting (bug #139109) Patch from

View file

@ -409,6 +409,18 @@ AC_HELP_STRING([--disable-debug],[disable addition of -g debugging info]),
esac],
[USE_DEBUG=yes]) dnl Default value
dnl valgrind inclusion
USE_VALGRIND="$USE_DEBUG"
if test "x$USE_VALGRIND" = xyes; then
PKG_CHECK_MODULES(VALGRIND, valgrind, USE_VALGRIND="yes", USE_VALGRIND="no")
fi
if test "x$USE_VALGRIND" = xyes; then
AC_DEFINE(HAVE_VALGRIND, 1, [Define if valgrind should be used])
AC_MSG_NOTICE(Using extra code paths for valgrind)
fi
AC_SUBST (VALGRIND_CFLAGS)
AC_SUBST (VALGRIND_LIBS)
dnl ################################################
dnl # Set defines according to variables set above #
dnl ################################################

View file

@ -142,10 +142,11 @@ DISTCLEANFILES = $(built_header_configure)
libgstreamer_@GST_MAJORMINOR@_la_CFLAGS = \
-D_GNU_SOURCE \
$(GST_CFLAGS) \
$(VALGRIND_CFLAGS) \
-DG_LOG_DOMAIN=g_log_domain_gstreamer \
-DGST_MAJORMINOR=\""$(GST_MAJORMINOR)"\"
libgstreamer_@GST_MAJORMINOR@_la_LIBADD = \
$(LIBGST_LIBS) $(GST_PARSE_LIBADD) $(GST_REGISTRY_LIBADD)
$(LIBGST_LIBS) $(GST_PARSE_LIBADD) $(GST_REGISTRY_LIBADD) $(VALGRIND_LIBS)
libgstreamer_@GST_MAJORMINOR@_la_LDFLAGS = \
@GST_LT_LDFLAGS@ -version-info @GST_LIBVERSION@

View file

@ -28,9 +28,13 @@
# include "config.h"
#endif
#include <glib.h>
#include <stdlib.h>
#include <string.h>
gboolean __gst_in_valgrind (void);
/*** debugging categories *****************************************************/
#ifndef GST_DISABLE_GST_DEBUG

View file

@ -43,6 +43,9 @@
#include "gstpad.h"
#include "gstscheduler.h"
#include "gst_private.h"
#ifdef HAVE_VALGRIND
#include <valgrind/valgrind.h>
#endif
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEBUG);
@ -155,6 +158,41 @@ GstDebugCategory *GST_CAT_PARAMS = NULL;
GstDebugCategory *GST_CAT_CALL_TRACE = NULL;
GstDebugCategory *GST_CAT_SEEK = NULL;
/* FIXME: export this? */
gboolean
__gst_in_valgrind (void)
{
static enum
{
GST_VG_UNCHECKED,
GST_VG_NO_VALGRIND,
GST_VG_INSIDE
}
in_valgrind = GST_VG_UNCHECKED;
if (in_valgrind == GST_VG_UNCHECKED) {
#ifdef HAVE_VALGRIND
if (RUNNING_ON_VALGRIND) {
GST_CAT_INFO (GST_CAT_GST_INIT, "we're running inside valgrind");
VALGRIND_PRINTF
("GStreamer has detected that it is running inside valgrind.");
VALGRIND_PRINTF
("It might now take different code paths to ease debugging.");
VALGRIND_PRINTF ("Of course, this may also lead to different bugs.");
in_valgrind = GST_VG_INSIDE;
} else {
GST_CAT_LOG (GST_CAT_GST_INIT, "not doing extra valgrind stuff");
in_valgrind = GST_VG_NO_VALGRIND;
}
#else
in_valgrind = GST_VG_NO_VALGRIND;
#endif
g_assert (in_valgrind == GST_VG_NO_VALGRIND ||
in_valgrind == GST_VG_INSIDE);
}
return (in_valgrind == GST_VG_INSIDE) ? TRUE : FALSE;
}
/**
* _gst_debug_init:
*
@ -240,6 +278,9 @@ _gst_debug_init (void)
GST_DEBUG_BOLD, NULL);
GST_CAT_SEEK = _gst_debug_category_new ("GST_SEEK",
0, "plugins reacting to seek events");
/* print out the valgrind message if we're in valgrind */
__gst_in_valgrind ();
}
/* we can't do this further above, because we initialize the GST_CAT_DEFAULT struct */

View file

@ -16,6 +16,7 @@
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include "gst_private.h"
#include <string.h> /* memset */
@ -23,6 +24,11 @@
#include "gstutils.h"
#include "gstmemchunk.h"
#include "gsttrashstack.h"
#ifdef HAVE_VALGRIND
#include <sys/mman.h>
#include <valgrind/valgrind.h>
#endif
#define GST_MEM_CHUNK_AREA(chunk) (((GstMemChunkElement*)(chunk))->area)
#define GST_MEM_CHUNK_DATA(chunk) ((gpointer)(((GstMemChunkElement*)(chunk)) + 1))
@ -67,7 +73,18 @@ populate (GstMemChunk * mem_chunk)
if (mem_chunk->cleanup)
return FALSE;
area = (guint8 *) g_malloc0 (mem_chunk->area_size);
/* FIXME: if we don't do this here and use g_malloc, valgrind crashes */
#if HAVE_VALGRIND
if (__gst_in_valgrind ()) {
/* copied from valgrind example */
area =
(guint8 *) mmap (0, mem_chunk->area_size,
PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANON, -1, 0);
} else
#endif
{
area = g_malloc0 (mem_chunk->area_size);
}
for (i = 0; i < mem_chunk->area_size; i += mem_chunk->chunk_size) {
GST_MEM_CHUNK_AREA (area + i) = area;
@ -117,7 +134,17 @@ gst_mem_chunk_new (gchar * name, gint atom_size, gulong area_size, gint type)
static gboolean
free_area (gpointer key, gpointer value, gpointer user_data)
{
g_free (key);
#if HAVE_VALGRIND
GstMemChunk *chunk = (GstMemChunk *) user_data;
if (__gst_in_valgrind ()) {
/* copied from valgrind example */
munmap (key, chunk->area_size);
} else
#endif
{
g_free (key);
}
return TRUE;
}
@ -144,7 +171,7 @@ gst_mem_chunk_destroy (GstMemChunk * mem_chunk)
data = gst_mem_chunk_alloc (mem_chunk);
}
g_hash_table_foreach_remove (elements, free_area, NULL);
g_hash_table_foreach_remove (elements, free_area, mem_chunk);
g_hash_table_destroy (elements);
g_free (mem_chunk->name);
@ -177,7 +204,12 @@ again:
else
return NULL;
}
#ifdef HAVE_VALGRIND
//return g_malloc (mem_chunk->atom_size);
g_print ("alloc %p %lu\n", GST_MEM_CHUNK_DATA (chunk), mem_chunk->atom_size);
VALGRIND_MALLOCLIKE_BLOCK (GST_MEM_CHUNK_DATA (chunk), mem_chunk->atom_size,
0, 0);
#endif
return GST_MEM_CHUNK_DATA (chunk);
}
@ -219,5 +251,10 @@ gst_mem_chunk_free (GstMemChunk * mem_chunk, gpointer mem)
chunk = GST_MEM_CHUNK_LINK (mem);
#ifdef HAVE_VALGRIND
//g_free (mem);
VALGRIND_FREELIKE_BLOCK (mem, 0);
g_print ("free %p\n", mem);
#endif
gst_trash_stack_push (&mem_chunk->stack, chunk);
}