mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-07 07:58:51 +00:00
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:
parent
cce13e8e5c
commit
e0ab9b5740
6 changed files with 117 additions and 5 deletions
17
ChangeLog
17
ChangeLog
|
@ -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>
|
2004-04-05 David Schleef <ds@schleef.org>
|
||||||
|
|
||||||
* gst/gsttrace.h: Fix #ifdef nesting (bug #139109) Patch from
|
* gst/gsttrace.h: Fix #ifdef nesting (bug #139109) Patch from
|
||||||
|
|
12
configure.ac
12
configure.ac
|
@ -409,6 +409,18 @@ AC_HELP_STRING([--disable-debug],[disable addition of -g debugging info]),
|
||||||
esac],
|
esac],
|
||||||
[USE_DEBUG=yes]) dnl Default value
|
[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 ################################################
|
||||||
dnl # Set defines according to variables set above #
|
dnl # Set defines according to variables set above #
|
||||||
dnl ################################################
|
dnl ################################################
|
||||||
|
|
|
@ -142,10 +142,11 @@ DISTCLEANFILES = $(built_header_configure)
|
||||||
libgstreamer_@GST_MAJORMINOR@_la_CFLAGS = \
|
libgstreamer_@GST_MAJORMINOR@_la_CFLAGS = \
|
||||||
-D_GNU_SOURCE \
|
-D_GNU_SOURCE \
|
||||||
$(GST_CFLAGS) \
|
$(GST_CFLAGS) \
|
||||||
|
$(VALGRIND_CFLAGS) \
|
||||||
-DG_LOG_DOMAIN=g_log_domain_gstreamer \
|
-DG_LOG_DOMAIN=g_log_domain_gstreamer \
|
||||||
-DGST_MAJORMINOR=\""$(GST_MAJORMINOR)"\"
|
-DGST_MAJORMINOR=\""$(GST_MAJORMINOR)"\"
|
||||||
libgstreamer_@GST_MAJORMINOR@_la_LIBADD = \
|
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 = \
|
libgstreamer_@GST_MAJORMINOR@_la_LDFLAGS = \
|
||||||
@GST_LT_LDFLAGS@ -version-info @GST_LIBVERSION@
|
@GST_LT_LDFLAGS@ -version-info @GST_LIBVERSION@
|
||||||
|
|
||||||
|
|
|
@ -28,9 +28,13 @@
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
gboolean __gst_in_valgrind (void);
|
||||||
|
|
||||||
/*** debugging categories *****************************************************/
|
/*** debugging categories *****************************************************/
|
||||||
|
|
||||||
#ifndef GST_DISABLE_GST_DEBUG
|
#ifndef GST_DISABLE_GST_DEBUG
|
||||||
|
|
|
@ -43,6 +43,9 @@
|
||||||
#include "gstpad.h"
|
#include "gstpad.h"
|
||||||
#include "gstscheduler.h"
|
#include "gstscheduler.h"
|
||||||
#include "gst_private.h"
|
#include "gst_private.h"
|
||||||
|
#ifdef HAVE_VALGRIND
|
||||||
|
#include <valgrind/valgrind.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEBUG);
|
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_CALL_TRACE = NULL;
|
||||||
GstDebugCategory *GST_CAT_SEEK = 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:
|
* _gst_debug_init:
|
||||||
*
|
*
|
||||||
|
@ -240,6 +278,9 @@ _gst_debug_init (void)
|
||||||
GST_DEBUG_BOLD, NULL);
|
GST_DEBUG_BOLD, NULL);
|
||||||
GST_CAT_SEEK = _gst_debug_category_new ("GST_SEEK",
|
GST_CAT_SEEK = _gst_debug_category_new ("GST_SEEK",
|
||||||
0, "plugins reacting to seek events");
|
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 */
|
/* we can't do this further above, because we initialize the GST_CAT_DEFAULT struct */
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
#include "gst_private.h"
|
||||||
|
|
||||||
#include <string.h> /* memset */
|
#include <string.h> /* memset */
|
||||||
|
|
||||||
|
@ -23,6 +24,11 @@
|
||||||
#include "gstutils.h"
|
#include "gstutils.h"
|
||||||
#include "gstmemchunk.h"
|
#include "gstmemchunk.h"
|
||||||
#include "gsttrashstack.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_AREA(chunk) (((GstMemChunkElement*)(chunk))->area)
|
||||||
#define GST_MEM_CHUNK_DATA(chunk) ((gpointer)(((GstMemChunkElement*)(chunk)) + 1))
|
#define GST_MEM_CHUNK_DATA(chunk) ((gpointer)(((GstMemChunkElement*)(chunk)) + 1))
|
||||||
|
@ -67,7 +73,18 @@ populate (GstMemChunk * mem_chunk)
|
||||||
if (mem_chunk->cleanup)
|
if (mem_chunk->cleanup)
|
||||||
return FALSE;
|
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) {
|
for (i = 0; i < mem_chunk->area_size; i += mem_chunk->chunk_size) {
|
||||||
GST_MEM_CHUNK_AREA (area + i) = area;
|
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
|
static gboolean
|
||||||
free_area (gpointer key, gpointer value, gpointer user_data)
|
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;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -144,7 +171,7 @@ gst_mem_chunk_destroy (GstMemChunk * mem_chunk)
|
||||||
|
|
||||||
data = gst_mem_chunk_alloc (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_hash_table_destroy (elements);
|
||||||
g_free (mem_chunk->name);
|
g_free (mem_chunk->name);
|
||||||
|
@ -177,7 +204,12 @@ again:
|
||||||
else
|
else
|
||||||
return NULL;
|
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);
|
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);
|
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);
|
gst_trash_stack_push (&mem_chunk->stack, chunk);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue