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 <Eina.h>

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



SVN revision: 53405
This commit is contained in:
Rafael Fonseca 2010-10-14 15:18:15 +00:00
parent 6d6f5c7360
commit 6485492cbe
3 changed files with 56 additions and 2 deletions

View File

@ -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@:>@])],

View File

@ -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

View File

@ -45,6 +45,10 @@
#include "eina_private.h"
#ifndef NVALGRIND
# include <valgrind/memcheck.h>
#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