summaryrefslogtreecommitdiffstats
path: root/libdm
diff options
context:
space:
mode:
authorJoe Thornber <thornber@redhat.com>2010-08-09 10:56:01 +0000
committerJoe Thornber <thornber@redhat.com>2010-08-09 10:56:01 +0000
commit52e1564fddf769d481ef8bc89a01c680777bcbbc (patch)
tree9ebf3a6c825029c278ec2300ab2bec33f9b7fc36 /libdm
parentfae2c492595add56718d45efaee36438e4279600 (diff)
downloadlvm2-52e1564fddf769d481ef8bc89a01c680777bcbbc.tar.gz
lvm2-52e1564fddf769d481ef8bc89a01c680777bcbbc.tar.xz
lvm2-52e1564fddf769d481ef8bc89a01c680777bcbbc.zip
[MM] Make valgrind aware of the pool allocators
./configure with --enable-valgrind-pool to enable this.
Diffstat (limited to 'libdm')
-rw-r--r--libdm/mm/dbg_malloc.c8
-rw-r--r--libdm/mm/pool-fast.c63
2 files changed, 63 insertions, 8 deletions
diff --git a/libdm/mm/dbg_malloc.c b/libdm/mm/dbg_malloc.c
index d86326db..cace8110 100644
--- a/libdm/mm/dbg_malloc.c
+++ b/libdm/mm/dbg_malloc.c
@@ -193,6 +193,13 @@ int dm_dump_memory_debug(void)
log_very_verbose("You have a memory leak:");
for (mb = _head; mb; mb = mb->next) {
+#ifdef VALGRIND_POOL
+ /*
+ * We can't look at the memory in case it has had
+ * VALGRIND_MAKE_MEM_NOACCESS called on it.
+ */
+ str[0] = '\0';
+#else
for (c = 0; c < sizeof(str) - 1; c++) {
if (c >= mb->length)
str[c] = ' ';
@@ -204,6 +211,7 @@ int dm_dump_memory_debug(void)
str[c] = ((char *)mb->magic)[c];
}
str[sizeof(str) - 1] = '\0';
+#endif
LOG_MESG(_LOG_INFO, mb->file, mb->line, 0,
"block %d at %p, size %" PRIsize_t "\t [%s]",
diff --git a/libdm/mm/pool-fast.c b/libdm/mm/pool-fast.c
index c8f3429e..daad79aa 100644
--- a/libdm/mm/pool-fast.c
+++ b/libdm/mm/pool-fast.c
@@ -1,6 +1,6 @@
/*
- * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
- * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
+ * Copyright (C) 2004-2010 Red Hat, Inc. All rights reserved.
*
* This file is part of the device-mapper userspace tools.
*
@@ -13,6 +13,10 @@
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#ifdef VALGRIND_POOL
+#include "valgrind/memcheck.h"
+#endif
+
#include "dmlib.h"
struct chunk {
@@ -31,6 +35,7 @@ struct dm_pool {
void _align_chunk(struct chunk *c, unsigned alignment);
struct chunk *_new_chunk(struct dm_pool *p, size_t s);
+static void _free_chunk(struct chunk *c);
/* by default things come out aligned for doubles */
#define DEFAULT_ALIGNMENT __alignof__ (double)
@@ -59,11 +64,11 @@ struct dm_pool *dm_pool_create(const char *name, size_t chunk_hint)
void dm_pool_destroy(struct dm_pool *p)
{
struct chunk *c, *pr;
- dm_free(p->spare_chunk);
+ _free_chunk(p->spare_chunk);
c = p->chunk;
while (c) {
pr = c->prev;
- dm_free(c);
+ _free_chunk(c);
c = pr;
}
@@ -100,6 +105,11 @@ void *dm_pool_alloc_aligned(struct dm_pool *p, size_t s, unsigned alignment)
r = c->begin;
c->begin += s;
+
+#ifdef VALGRIND_POOL
+ VALGRIND_MAKE_MEM_UNDEFINED(r, s);
+#endif
+
return r;
}
@@ -122,11 +132,20 @@ void dm_pool_free(struct dm_pool *p, void *ptr)
if (((char *) c < (char *) ptr) &&
((char *) c->end > (char *) ptr)) {
c->begin = ptr;
+#ifdef VALGRIND_POOL
+ VALGRIND_MAKE_MEM_NOACCESS(c->begin, c->end - c->begin);
+#endif
break;
}
if (p->spare_chunk)
- dm_free(p->spare_chunk);
+ _free_chunk(p->spare_chunk);
+
+ c->begin = (char *) (c + 1);
+#ifdef VALGRIND_POOL
+ VALGRIND_MAKE_MEM_NOACCESS(c->begin, c->end - c->begin);
+#endif
+
p->spare_chunk = c;
c = c->prev;
}
@@ -183,10 +202,24 @@ int dm_pool_grow_object(struct dm_pool *p, const void *extra, size_t delta)
return 0;
_align_chunk(p->chunk, p->object_alignment);
+
+#ifdef VALGRIND_POOL
+ VALGRIND_MAKE_MEM_UNDEFINED(p->chunk->begin, p->object_len);
+#endif
+
memcpy(p->chunk->begin, c->begin, p->object_len);
+
+#ifdef VALGRIND_POOL
+ VALGRIND_MAKE_MEM_NOACCESS(c->begin, p->object_len);
+#endif
+
c = p->chunk;
}
+#ifdef VALGRIND_POOL
+ VALGRIND_MAKE_MEM_UNDEFINED(p->chunk->begin + p->object_len, delta);
+#endif
+
memcpy(c->begin + p->object_len, extra, delta);
p->object_len += delta;
return 1;
@@ -218,7 +251,7 @@ struct chunk *_new_chunk(struct dm_pool *p, size_t s)
struct chunk *c;
if (p->spare_chunk &&
- ((p->spare_chunk->end - (char *) p->spare_chunk) >= s)) {
+ ((p->spare_chunk->end - p->spare_chunk->begin) >= s)) {
/* reuse old chunk */
c = p->spare_chunk;
p->spare_chunk = 0;
@@ -229,12 +262,26 @@ struct chunk *_new_chunk(struct dm_pool *p, size_t s)
return NULL;
}
+ c->begin = (char *) (c + 1);
c->end = (char *) c + s;
+
+#ifdef VALGRIND_POOL
+ VALGRIND_MAKE_MEM_NOACCESS(c->begin, c->end - c->begin);
+#endif
}
c->prev = p->chunk;
- c->begin = (char *) (c + 1);
p->chunk = c;
-
return c;
}
+
+static void _free_chunk(struct chunk *c)
+{
+ if (c) {
+#ifdef VALGRIND_POOL
+ VALGRIND_MAKE_MEM_UNDEFINED(c, c->end - (char *) c);
+#endif
+
+ dm_free(c);
+ }
+}