? src/lib/compat-gc.h
? src/lib/diff
? src/lib/q
? src/lib/reader
? src/lib/test
? src/lib/test-read
? src/lib/test-read.c
? src/lib/test-send
? src/lib/test-send.c
? src/lib/test.c
Index: src/lib/Makefile.am
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib/Makefile.am,v
retrieving revision 1.62.2.2
diff -u -r1.62.2.2 Makefile.am
--- src/lib/Makefile.am	16 Aug 2006 15:54:56 -0000	1.62.2.2
+++ src/lib/Makefile.am	18 Nov 2006 22:56:27 -0000
@@ -45,6 +45,7 @@
 	lib-signals.c \
 	md4.c \
 	md5.c \
+	memdebug.c \
 	mempool.c \
 	mempool-alloconly.c \
 	mempool-datastack.c \
@@ -122,6 +123,7 @@
 	macros.h \
 	md4.h \
 	md5.h \
+	memdebug.h \
 	mempool.h \
 	mkdir-parents.h \
 	mmap-util.h \
Index: src/lib/data-stack.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib/data-stack.c,v
retrieving revision 1.24.2.2
diff -u -r1.24.2.2 data-stack.c
--- src/lib/data-stack.c	10 Sep 2006 17:59:47 -0000	1.24.2.2
+++ src/lib/data-stack.c	18 Nov 2006 22:56:27 -0000
@@ -3,6 +3,7 @@
 /* @UNSAFE: whole file */
 
 #include "lib.h"
+#include "memdebug.h"
 #include "data-stack.h"
 
 #include <stdlib.h>
@@ -13,6 +14,12 @@
 #  include <gc.h>
 #endif
 
+#ifdef MEMDEBUG
+#  define malloc(size) memdebug_malloc(size)
+#  define calloc(count, size) memdebug_calloc(count, size)
+#  define free(ptr) memdebug_free(ptr)
+#endif
+
 /* Use malloc() and free() for all memory allocations. Useful for debugging
    memory corruption. */
 /* #define DISABLE_DATA_STACK */
Index: src/lib/memdebug.c
===================================================================
RCS file: src/lib/memdebug.c
diff -N src/lib/memdebug.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/lib/memdebug.c	18 Nov 2006 22:56:27 -0000
@@ -0,0 +1,89 @@
+/* Copyright (c) 2006 Timo Sirainen */
+
+#include "lib.h"
+#include "memdebug.h"
+
+#ifdef MEMDEBUG
+#include <stdlib.h>
+
+#define SENTRY_SIZE 32
+#define MALLOC_EXTRA (SENTRY_SIZE * 2 + sizeof(size_t))
+
+static void *setup_sentry(unsigned char *data, size_t size)
+{
+	unsigned char checksum = 0;
+	unsigned int i, j;
+
+	memcpy(data, &size, sizeof(size));
+	data += sizeof(size);
+
+	for (i = 0; i < SENTRY_SIZE-1; i++) {
+		data[i] = rand();
+		checksum = (checksum << 4) ^ data[i];
+	}
+	data[i] = checksum;
+
+	for (i = 0, j = size + SENTRY_SIZE; i < SENTRY_SIZE-1; i++, j++) {
+		data[j] = rand();
+		checksum = (checksum << 4) ^ data[j];
+	}
+	data[j] = checksum;
+	return data + SENTRY_SIZE;
+}
+
+static void *verify_sentry(unsigned char *data)
+{
+	unsigned char checksum = 0;
+	unsigned int i, j;
+	size_t size;
+
+	data -= sizeof(size) + SENTRY_SIZE;
+	memcpy(&size, data, sizeof(size));
+	data += sizeof(size);
+
+	for (i = 0; i < SENTRY_SIZE-1; i++)
+		checksum = (checksum << 4) ^ data[i];
+	if (data[i] != checksum)
+		i_panic("buffer underflow");
+
+	for (i = 0, j = size + SENTRY_SIZE; i < SENTRY_SIZE-1; i++, j++)
+		checksum = (checksum << 4) ^ data[j];
+	if (data[j] != checksum)
+		i_panic("buffer overflow");
+
+	return data - sizeof(size);
+}
+
+void *memdebug_malloc(size_t size)
+{
+	return setup_sentry(malloc(size + MALLOC_EXTRA), size);
+}
+
+void *memdebug_calloc(size_t count, size_t size)
+{
+	i_assert((size_t)-1 / size > count);
+
+	return setup_sentry(calloc(1, count*size + MALLOC_EXTRA), count * size);
+}
+
+void *memdebug_realloc(void *ptr, size_t size)
+{
+	unsigned char *data = ptr;
+
+	if (data == NULL)
+		return memdebug_malloc(size);
+
+	data = verify_sentry(data);
+	return setup_sentry(realloc(data, size + MALLOC_EXTRA), size);
+}
+
+void memdebug_free(void *ptr)
+{
+	unsigned char *data = ptr;
+
+	if (data != NULL) {
+		data = verify_sentry(data);
+		free(data);
+	}
+}
+#endif
Index: src/lib/memdebug.h
===================================================================
RCS file: src/lib/memdebug.h
diff -N src/lib/memdebug.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/lib/memdebug.h	18 Nov 2006 22:56:27 -0000
@@ -0,0 +1,11 @@
+#ifndef __MEMDEBUG_H
+#define __MEMDEBUG_H
+
+#define MEMDEBUG
+
+void *memdebug_malloc(size_t size);
+void *memdebug_calloc(size_t count, size_t size);
+void *memdebug_realloc(void *ptr, size_t size);
+void memdebug_free(void *ptr);
+
+#endif
Index: src/lib/mempool-alloconly.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib/mempool-alloconly.c,v
retrieving revision 1.35.2.3
diff -u -r1.35.2.3 mempool-alloconly.c
--- src/lib/mempool-alloconly.c	10 Sep 2006 17:49:06 -0000	1.35.2.3
+++ src/lib/mempool-alloconly.c	18 Nov 2006 22:56:27 -0000
@@ -2,6 +2,7 @@
 
 /* @UNSAFE: whole file */
 #include "lib.h"
+#include "memdebug.h"
 #include "mempool.h"
 
 #include <stdlib.h>
@@ -12,6 +13,11 @@
 #  include <gc.h>
 #endif
 
+#ifdef MEMDEBUG
+#  define calloc(count, size) memdebug_calloc(count, size)
+#  define free(ptr) memdebug_free(ptr)
+#endif
+
 #define MAX_ALLOC_SIZE SSIZE_T_MAX
 
 struct alloconly_pool {
Index: src/lib/mempool-system.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib/mempool-system.c,v
retrieving revision 1.18.2.1
diff -u -r1.18.2.1 mempool-system.c
--- src/lib/mempool-system.c	10 Sep 2006 17:49:06 -0000	1.18.2.1
+++ src/lib/mempool-system.c	18 Nov 2006 22:56:27 -0000
@@ -3,6 +3,7 @@
 /* @UNSAFE: whole file */
 
 #include "lib.h"
+#include "memdebug.h"
 #include "mempool.h"
 
 #include <stdlib.h>
@@ -13,6 +14,13 @@
 #  include <gc.h>
 #endif
 
+#ifdef MEMDEBUG
+#  define malloc(size) memdebug_malloc(size)
+#  define calloc(count, size) memdebug_calloc(count, size)
+#  define realloc(ptr, size) memdebug_realloc(ptr, size)
+#  define free(ptr) memdebug_free(ptr)
+#endif
+
 static const char *pool_system_get_name(pool_t pool);
 static void pool_system_ref(pool_t pool);
 static void pool_system_unref(pool_t *pool);
