From d09a8cf5c1fd2615bd256aa69d7fb3226d7d119d Mon Sep 17 00:00:00 2001 From: rfonseca Date: Thu, 14 Oct 2010 15:18:15 +0000 Subject: [PATCH] Make valgrind know about eina mempools. Because mempools generally allocate a big memory area and distribute chunks of that area to the users, valgrind can not know about logical invalid access. By using some valgrind macros we can tell valgrind about mempools and which area can be accessed or not. To start with I have just done valgrind integration on chained mempool but soon it will be done for one_big too. The code below is an example on which valgrind wouldn't complain without this patch: @code #include int main(int argc, char *argv[]) { int i, *pool[4]; Eina_Mempool *mp; eina_init(); mp = eina_mempool_add("chained_mempool", "test", NULL, sizeof(int), 4); for (i = 0; i < 4; i++) { pool[i] = eina_mempool_malloc(mp, sizeof(int)); *pool[i] = i; } printf("Valid mp pointer: pool[0] = %d\n", *pool[0]); eina_mempool_free(mp, pool[0]); printf("Freed mp pointer: pool[0] = %d\n", *pool[0]); for (i = 1; i < 4; i++) eina_mempool_free(mp, pool[i]); eina_mempool_del(mp); eina_shutdown(); return 0; } @endcode git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/eina@53405 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33 --- configure.ac | 26 +++++++++++++++++++ src/modules/mp/chained_pool/Makefile.am | 3 ++- src/modules/mp/chained_pool/eina_chained_mempool.c | 29 +++++++++++++++++++++- 3 files changed, 56 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 6074c6e..b0fc28f 100644 --- a/configure.ac +++ b/configure.ac @@ -121,6 +121,32 @@ if test "x${have_magic_debug}" = "xyes" ; then fi AC_SUBST(EINA_CONFIGURE_MAGIC_DEBUG) +# Valgrind +want_valgrind="no" + +AC_MSG_CHECKING(whether to enable build with valgrind) +AC_ARG_ENABLE(valgrind, + AC_HELP_STRING([--enable-valgrind], [enable valgrind fixes to stop false reports]), + [want_valgrind=$enableval] +) +AC_MSG_RESULT($want_valgrind) + +if test x$want_valgrind = "xyes"; then + PKG_CHECK_MODULES(VALGRIND, valgrind >= 2.4.0, + [ + requirement_eina="valgrind ${requirement_eina}" + ], + [ + AC_DEFINE(NVALGRIND, 1, [Valgrind support disabled]) + if test "x$want_valgrind" = "xyes"; then + AC_MSG_ERROR([Valgrind >= 2.4.0 is required)]) + fi + ] + ) +else + AC_DEFINE(NVALGRIND, 1, [Valgrind support disabled]) +fi + # Safety checks (avoid crashes on wrong api usage) AC_ARG_ENABLE(safety-checks, [AC_HELP_STRING([--disable-safety-checks], [disable safety checks for NULL pointers and like. @<:@default=enabled@:>@])], diff --git a/src/modules/mp/chained_pool/Makefile.am b/src/modules/mp/chained_pool/Makefile.am index 584fb82..e5394f3 100644 --- a/src/modules/mp/chained_pool/Makefile.am +++ b/src/modules/mp/chained_pool/Makefile.am @@ -7,7 +7,8 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/lib \ -I$(top_builddir)/src/lib \ @EINA_CPPFLAGS@ \ -@EFL_EINA_BUILD@ +@EFL_EINA_BUILD@ \ +@VALGRIND_CFLAGS@ if EINA_BUILD_CHAINED_POOL if !EINA_STATIC_BUILD_CHAINED_POOL diff --git a/src/modules/mp/chained_pool/eina_chained_mempool.c b/src/modules/mp/chained_pool/eina_chained_mempool.c index 49cacc6..fac12f5 100644 --- a/src/modules/mp/chained_pool/eina_chained_mempool.c +++ b/src/modules/mp/chained_pool/eina_chained_mempool.c @@ -45,6 +45,10 @@ #include "eina_private.h" +#ifndef NVALGRIND +# include +#endif + #ifdef DEBUG #include "eina_log.h" @@ -94,6 +98,7 @@ _eina_chained_mp_pool_new(Chained_Mempool *pool) { Chained_Pool *p; unsigned char *ptr; + unsigned int alignof; eina_error_set(0); p = malloc(pool->alloc_size); @@ -103,12 +108,18 @@ _eina_chained_mp_pool_new(Chained_Mempool *pool) return NULL; } - ptr = (unsigned char *)p + eina_mempool_alignof(sizeof(Chained_Pool)); + alignof = eina_mempool_alignof(sizeof(Chained_Pool)); + ptr = (unsigned char *)p + alignof; p->usage = 0; p->base = NULL; p->last = ptr; p->limit = ptr + pool->item_alloc * pool->pool_size; + +#ifndef NVALGRIND + VALGRIND_MAKE_MEM_NOACCESS(ptr, pool->alloc_size - alignof); +#endif + return p; } @@ -202,6 +213,10 @@ eina_chained_mempool_malloc(void *data, __UNUSED__ unsigned int size) } #endif +#ifndef NVALGRIND + VALGRIND_MEMPOOL_ALLOC(pool, mem, pool->item_alloc); +#endif + return mem; } @@ -231,6 +246,10 @@ eina_chained_mempool_free(void *data, void *ptr) #endif #endif +#ifndef NVALGRIND + VALGRIND_MEMPOOL_FREE(pool, ptr); +#endif + EINA_INLIST_FOREACH(pool->first, p) { // Could the pointer be inside that pool @@ -309,6 +328,10 @@ eina_chained_mempool_init(const char *context, mp->group_size = mp->item_alloc * mp->pool_size; mp->alloc_size = mp->group_size + eina_mempool_alignof(sizeof(Chained_Pool)); +#ifndef NVALGRIND + VALGRIND_CREATE_MEMPOOL(mp, 0, 1); +#endif + #ifdef EFL_HAVE_THREADS # ifdef EFL_HAVE_POSIX_THREADS # ifdef EFL_DEBUG_THREADS @@ -345,6 +368,10 @@ eina_chained_mempool_shutdown(void *data) _eina_chained_mp_pool_free(p); } +#ifndef NVALGRIND + VALGRIND_DESTROY_MEMPOOL(mp); +#endif + #ifdef EFL_HAVE_THREADS # ifdef EFL_HAVE_POSIX_THREADS # ifdef EFL_DEBUG_THREADS -- 2.7.4