diff -ruN x/diablo-5-CUR-20090530-00.patched/XMakefile.inc diablo-5-CUR-20090530-00/XMakefile.inc
--- x/diablo-5-CUR-20090530-00.patched/XMakefile.inc	2011-07-11 14:54:28.000000000 +0200
+++ diablo-5-CUR-20090530-00/XMakefile.inc	2011-07-09 16:54:41.000000000 +0200
@@ -9,7 +9,7 @@
 .set DLIB	"$(BD)obj/libdiablo.a"
 .set FLIB	"$(BD)obj/libfilter.a"
 .set RLIB	"$(BD)obj/libdreader.a"
-.set CDEFINES	'-DVERS="$(VERS)"' '-DSUBREV="$(SUBREV)"'
+.set CDEFINES	'-DVERS="$(VERS)"' '-DSUBREV="$(SUBREV)"' '-DDEBUG_ZALLOC' '-DDEBUG_MBUF'
 #if __GNUC__
 .set CFLAGS	-g -O2 -Wall -Wstrict-prototypes "-I$(BD)" $(CDEFINES)
 .set LSTATIC
diff -ruN x/diablo-5-CUR-20090530-00.patched/dreaderd/defs.h diablo-5-CUR-20090530-00/dreaderd/defs.h
--- x/diablo-5-CUR-20090530-00.patched/dreaderd/defs.h	2009-01-23 16:37:55.000000000 +0100
+++ diablo-5-CUR-20090530-00/dreaderd/defs.h	2011-07-09 12:17:31.000000000 +0200
@@ -691,3 +691,5 @@
 
 #include <obj/dreaderd-protos.h>
 
+#include <lib/debug-mbuf.h>
+
diff -ruN x/diablo-5-CUR-20090530-00.patched/dreaderd/main.c diablo-5-CUR-20090530-00/dreaderd/main.c
--- x/diablo-5-CUR-20090530-00.patched/dreaderd/main.c	2011-07-11 14:54:07.000000000 +0200
+++ diablo-5-CUR-20090530-00/dreaderd/main.c	2011-07-12 00:13:33.000000000 +0200
@@ -211,6 +211,10 @@
 
     LoadDiabloConfig(ac, av);
 
+#ifdef DEBUG_ZALLOC
+    dbg_install_sighandler();
+#endif
+
     if (strcmp(DRIncomingLogPat, "NONE") == 0)
 	DRIncomingLogPat = NULL;
     else
diff -ruN x/diablo-5-CUR-20090530-00.patched/dreaderd/mbuf.c diablo-5-CUR-20090530-00/dreaderd/mbuf.c
--- x/diablo-5-CUR-20090530-00.patched/dreaderd/mbuf.c	2009-01-23 05:17:35.000000000 +0100
+++ diablo-5-CUR-20090530-00/dreaderd/mbuf.c	2011-07-13 01:05:35.000000000 +0200
@@ -11,6 +11,8 @@
  *    for specific rights granted.
  */
 
+#define DEBUG_MBUF_OFF
+#define DEBUG_ZALLOC_OFF
 #include "defs.h"
 
 Prototype void MBFlush(Connection *conn, MBufHead *mh);
diff -ruN x/diablo-5-CUR-20090530-00.patched/lib/debug-mbuf.h diablo-5-CUR-20090530-00/lib/debug-mbuf.h
--- x/diablo-5-CUR-20090530-00.patched/lib/debug-mbuf.h	1970-01-01 01:00:00.000000000 +0100
+++ diablo-5-CUR-20090530-00/lib/debug-mbuf.h	2011-07-10 12:51:38.000000000 +0200
@@ -0,0 +1,38 @@
+#ifndef LIB_DEBUG_MBUF_H
+#define LIB_DEBUG_MBUF_H
+
+#if defined(DEBUG_MBUF) && !defined(DEBUG_MBUF_OFF)
+
+extern char *__dbg_file;
+extern char *__dbg_func;
+extern int __dbg_line;
+
+#  ifndef __dbg
+#    define __dbg(func, args...) ({ \
+                __dbg_line = __LINE__; \
+                __dbg_file = __FILE__; \
+                __dbg_func = #func; \
+                func(args); \
+          })
+#  endif
+
+#define MBFlush(args...)	__dbg(MBFlush, args)
+#define MBFree(args...)		__dbg(MBFree, args)
+#define MBPoll(args...)		__dbg(MBPoll, args)
+#define MBInit(args...)		__dbg(MBInit, args)
+#define MBWrite(args...)	__dbg(MBWrite, args)
+#define MZInit(args...)		__dbg(MZInit, args)
+#define MZWrite(args...)	__dbg(MZWrite, args)
+#define MZPrintf(args...)	__dbg(MZPrintf, args)
+#define MZFinish(args...)	__dbg(MZFinish, args)
+#define MBWriteDecode(args...)	__dbg(MBWriteDecode, args)
+#define MBCopy(args...)		__dbg(MBCopy, args)
+#define MBPrintf(args...)	__dbg(MBPrintf, args)
+#define MBLogPrintf(args...)	__dbg(MBLogPrintf, args)
+#define MBRead(args...)		__dbg(MBRead, args)
+#define MBReadLine(args...)	__dbg(MBReadLine, args)
+#define MBNormalize(args...)	__dbg(MBNormalize, args)
+
+#endif
+
+#endif
diff -ruN x/diablo-5-CUR-20090530-00.patched/lib/debug-zalloc.h diablo-5-CUR-20090530-00/lib/debug-zalloc.h
--- x/diablo-5-CUR-20090530-00.patched/lib/debug-zalloc.h	1970-01-01 01:00:00.000000000 +0100
+++ diablo-5-CUR-20090530-00/lib/debug-zalloc.h	2011-07-10 12:45:10.000000000 +0200
@@ -0,0 +1,32 @@
+#ifndef LIB_DEBUG_ZALLOC_H
+#define LIB_DEBUG_ZALLOC_H
+
+#if defined (DEBUG_ZALLOC) && !defined(DEBUG_ZALLOC_OFF)
+
+extern char *__dbg_file;
+extern char *__dbg_func;
+extern int __dbg_line;
+
+#  ifndef __dbg
+#    define __dbg(func, args...) ({ \
+		__dbg_line = __LINE__; \
+		__dbg_file = __FILE__; \
+		__dbg_func = #func; \
+		func(args); \
+	  })
+#  endif
+
+#  define nzalloc(args...)		__dbg(nzalloc, args)
+#  define zalloc(args...)		__dbg(zalloc, args)
+#  define zallocStr(args...)		__dbg(zallocStr, args)
+#  define zappendStr(args...)		__dbg(zappendStr, args)
+#  define zallocStrTrim(args...)	__dbg(zallocStrTrim, args)
+#  define zallocStrTrim2(args...)	__dbg(zallocStrTrim2, args)
+#  define zfree(args...)		__dbg(zfree, args)
+#  define zfreeStr(args...)		__dbg(zfreeStr, args)
+#  define allocPool(args...)		__dbg(allocPool, args)
+#  define freePool(args...)		__dbg(freePool, args)
+
+#endif
+
+#endif
diff -ruN x/diablo-5-CUR-20090530-00.patched/lib/defs.h diablo-5-CUR-20090530-00/lib/defs.h
--- x/diablo-5-CUR-20090530-00.patched/lib/defs.h	2011-07-11 14:54:28.000000000 +0200
+++ diablo-5-CUR-20090530-00/lib/defs.h	2011-07-09 12:16:01.000000000 +0200
@@ -891,6 +891,10 @@
 #include "obj/lib-protos.h"
 #endif
 
+#if defined(DEBUG_ZALLOC)
+#  include "debug-zalloc.h"
+#endif
+
 /*
  * can't use Prototype stuff for functions which may
  * already be prototyped.
diff -ruN x/diablo-5-CUR-20090530-00.patched/lib/mem.h diablo-5-CUR-20090530-00/lib/mem.h
--- x/diablo-5-CUR-20090530-00.patched/lib/mem.h	1998-10-12 04:33:35.000000000 +0200
+++ diablo-5-CUR-20090530-00/lib/mem.h	2011-07-09 14:15:47.000000000 +0200
@@ -18,5 +18,9 @@
     MemNode		*mp_First;
     int			mp_Size;
     int			mp_Used;
+#ifdef DEBUG_ZALLOC
+    unsigned long	mp_DzpId;
+    void		*mp_DzpPtr;
+#endif
 } MemPool;
 
diff -ruN x/diablo-5-CUR-20090530-00.patched/lib/zalloc.c diablo-5-CUR-20090530-00/lib/zalloc.c
--- x/diablo-5-CUR-20090530-00.patched/lib/zalloc.c	2011-07-11 14:54:07.000000000 +0200
+++ diablo-5-CUR-20090530-00/lib/zalloc.c	2011-07-13 01:08:04.000000000 +0200
@@ -23,6 +23,7 @@
  *    for specific rights granted.
  */
 
+#define DEBUG_ZALLOC_OFF
 #include "defs.h"
 
 #define POOLSIZE	65536
@@ -40,6 +41,18 @@
 Prototype void allocPool(MemPool **mpool, int bytes);
 Prototype void freePool(MemPool **mpool);
 
+#ifdef DEBUG_ZALLOC
+Prototype void dbg_install_sighandler(void);
+static void dbg_zalloc_add(MemPool *mp, char *dataptr, int bytes);
+static void dbg_zalloc_free(MemPool **pmp, char *dataptr, int bytes);
+static void dbg_zalloc_add_pool(MemPool **pmp, MemPool *mp);
+static void dbg_zalloc_free_pool(MemPool **pmp);
+
+char *__dbg_file;
+char *__dbg_func;
+int __dbg_line;
+#endif
+
 MemPool *initPool(int bytes);
 
 void *
@@ -71,6 +84,9 @@
                         *pmn = mn;
                     }
                     mp->mp_Used += bytes;
+#ifdef DEBUG_ZALLOC
+		    dbg_zalloc_add(mp, ptr, bytes);
+#endif
                     return(ptr);
                 }
             }
@@ -204,6 +220,10 @@
     /* 8 or 16-byte alignment required, depending on the pointer size */
     bytes = (bytes + MEMNODE_SIZE_MASK) & ~MEMNODE_SIZE_MASK;
 
+#ifdef DEBUG_ZALLOC
+    dbg_zalloc_free(pmp, ptr, bytes);
+#endif
+
     while ((mp = *pmp) != NULL) {
 	if ((char *)ptr >= (char *)mp->mp_Base && (char *)ptr < (char *)mp->mp_Base + mp->mp_Size) {
 	    MemNode **pmn;
@@ -292,6 +312,9 @@
     mp->mp_First = mp->mp_Base;
     mp->mp_First->mr_Next = NULL;
     mp->mp_First->mr_Bytes = mp->mp_Size;
+#ifdef DEBUG_ZALLOC
+    dbg_zalloc_add_pool(pmp, mp);
+#endif
     *pmp = mp;
 }
 
@@ -300,6 +323,10 @@
 {
     MemPool *mp;
 
+#ifdef DEBUG_ZALLOC
+    dbg_zalloc_free_pool(pmp);
+#endif
+
     while ((mp = *pmp) != NULL) {
 	*pmp = mp->mp_Next;
 	pagefree(mp->mp_Base, mp->mp_Size);
@@ -307,3 +334,260 @@
     }
 }
 
+#ifdef DEBUG_ZALLOC
+
+#define NODE_BUCKETS	512
+
+struct dbg_zalloc_node {
+    char *file;
+    int line;
+    char *func;
+    char *dataptr;
+    int bytes;
+    struct dbg_zalloc_node **pprevnext;
+    struct dbg_zalloc_node *next;
+};
+
+struct dbg_zalloc_pool {
+    char *file;
+    int line;
+    unsigned long id;
+    MemPool *mp;
+    struct dbg_zalloc_node *node[NODE_BUCKETS];
+    struct dbg_zalloc_pool **pprevnext;
+    struct dbg_zalloc_pool *next;
+};
+
+static struct dbg_zalloc_pool *dzpools;
+static int dbg_busy;
+
+static char *
+dbg_size(unsigned long sz, char *tmp)
+{
+    char *suffix = "";
+    char *fmt = "%lu (%.1f%s)";
+    double val;
+
+    if (sz > (1024*1024*1024)) {
+	val = (double)sz / (1024*1024*1024);
+	suffix = "G";
+    } else if (sz > (1024*1024)) {
+	val = (double)sz / (1024*1024);
+	suffix = "M";
+    } else if (sz > 1024) {
+	val = (double)sz / 1024;
+	suffix = "K";
+    } else {
+	val = sz;
+	fmt = "%lu (%.0f%s)";
+    }
+    if (val >= 4)
+	fmt = "%lu (%.0f%s)";
+    snprintf(tmp, 64, fmt, sz, val, suffix);
+    return tmp;
+}
+
+static void
+dbg_dump(int sig)
+{
+    struct dbg_zalloc_node *dzn;
+    struct dbg_zalloc_pool *dzp;
+    MemPool *mp;
+    unsigned long mp_Size, mp_Used;
+    char fn[128];
+    char tmp[128];
+    char tmp1[64], tmp2[64];
+    int i, fd;
+
+    snprintf(fn, sizeof(fn), "/news/run/dump.%ld.%ld",
+			(long)getpid(), (long)time(NULL));
+    fd = open(fn, O_CREAT|O_WRONLY|O_TRUNC, 0666);
+    if (fd < 0)
+	return;
+
+    __sync_synchronize();
+    if (dbg_busy) {
+	snprintf(tmp, sizeof(tmp), "cannot dump - datastructures are busy\n");
+	write(fd, tmp, strlen(tmp));
+	return;
+    }
+
+    for (dzp = dzpools; dzp; dzp = dzp->next) {
+	mp_Size = mp_Used = 0;
+	for (mp = dzp->mp; mp; mp = mp->mp_Next) {
+		mp_Size += mp->mp_Size;
+		mp_Used += mp->mp_Used;
+	}
+	snprintf(tmp, sizeof(tmp),
+		"pool %lu (from %s:%d) size: %s used: %s\n",
+		dzp->id, dzp->file, dzp->line,
+		dbg_size(mp_Size, tmp1), dbg_size(mp_Used, tmp2));
+	write(fd, tmp, strlen(tmp));
+	mp_Used = 0;
+	for (i = 0; i < NODE_BUCKETS; i++) {
+	    for (dzn = dzp->node[i]; dzn; dzn = dzn->next) {
+		snprintf(tmp, sizeof(tmp),
+			"  %s:%d %s allocated %d bytes @ %p\n",
+			dzn->file, dzn->line, dzn->func,
+			dzn->bytes, dzn->dataptr);
+		write(fd, tmp, strlen(tmp));
+		mp_Used += dzn->bytes;
+	    }
+	}
+	snprintf(tmp, sizeof(tmp), "all memnodes: %s\n\n",
+		dbg_size(mp_Used, tmp1));
+	write(fd, tmp, strlen(tmp));
+    }
+    write(fd, "\n", 1);
+    close(fd);
+}
+
+void
+dbg_install_sighandler(void)
+{
+    struct sigaction sa;
+
+    memset(&sa, 0, sizeof(sa));
+    sa.sa_handler = dbg_dump;
+    sa.sa_flags = SA_RESTART;
+    sigaction(SIGUSR2, &sa, NULL);
+}
+
+static struct dbg_zalloc_node *
+dbg_zalloc_find_node( struct dbg_zalloc_pool *dzp, char *dataptr)
+{
+    struct dbg_zalloc_node *dzn;
+    unsigned int h;
+
+    h = (unsigned long)dataptr % NODE_BUCKETS;
+    for (dzn = dzp->node[h]; dzn; dzn = dzn->next) {
+	if (dzn->dataptr == dataptr)
+	    break;
+    }
+    return dzn;
+}
+
+static void
+dbg_zalloc_add(MemPool *mp, char *dataptr, int bytes)
+{
+    struct dbg_zalloc_node *dzn;
+    struct dbg_zalloc_pool *dzp;
+    unsigned long h;
+
+    dzp = (struct dbg_zalloc_pool *)(mp->mp_DzpPtr);
+
+    dzn = malloc(sizeof(*dzn));
+    if (dzn == NULL)
+	kill(getpid(), SIGABRT);
+    dzn->file = __dbg_file;
+    dzn->line = __dbg_line;
+    dzn->func = __dbg_func;
+    dzn->dataptr = dataptr;
+    dzn->bytes = bytes;
+
+    dbg_busy++;
+    __sync_synchronize();
+    h = (unsigned long)dataptr % NODE_BUCKETS;
+    dzn->pprevnext = &dzp->node[h];
+    dzn->next = dzp->node[h];
+    if (dzp->node[h])
+	dzp->node[h]->pprevnext = &dzn->next;
+    dzp->node[h] = dzn;
+    __sync_synchronize();
+    dbg_busy--;
+}
+
+static void
+dbg_zalloc_free(MemPool **pmp, char *dataptr, int bytes)
+{
+    struct dbg_zalloc_node *dzn;
+    struct dbg_zalloc_pool *dzp;
+
+    if (*pmp == NULL)
+	return;
+
+    dzp = (struct dbg_zalloc_pool *)((*pmp)->mp_DzpPtr);
+    dzn = dbg_zalloc_find_node(dzp, dataptr);
+    if (dzn == NULL) {
+	logit(LOG_ERR, "dbg_zalloc_free: "
+			"cannot find dataptr %p", dataptr);
+	return;
+    }
+    dbg_busy++;
+    __sync_synchronize();
+    *(dzn->pprevnext) = dzn->next;
+    if (dzn->next)
+	dzn->next->pprevnext = dzn->pprevnext;
+    __sync_synchronize();
+    dbg_busy--;
+    free(dzn);
+}
+
+static void
+dbg_zalloc_add_pool(MemPool **pmp, MemPool *mp)
+{
+    struct dbg_zalloc_pool *dzp;
+    static unsigned long mempool_id;
+
+    if (*pmp) {
+	mp->mp_DzpPtr = (*pmp)->mp_DzpPtr;
+	mp->mp_DzpId = (*pmp)->mp_DzpId;
+	dzp = (*pmp)->mp_DzpPtr;
+	dzp->mp = mp;
+	return;
+    }
+
+    dzp = calloc(1, sizeof(*dzp));
+    if (dzp == NULL)
+	kill(getpid(), SIGABRT);
+    dzp->file = __dbg_file;
+    dzp->line = __dbg_line;
+    dzp->id = ++mempool_id;
+    dzp->mp = mp;
+
+    mp->mp_DzpPtr = dzp;
+    mp->mp_DzpId = dzp->id;
+    dzp->mp = mp;
+
+    dbg_busy++;
+    __sync_synchronize();
+    dzp->pprevnext = &dzpools;
+    dzp->next = dzpools;
+    if (dzpools)
+	dzpools->pprevnext = &dzp->next;
+    dzpools = dzp;
+    __sync_synchronize();
+    dbg_busy--;
+}
+
+static void
+dbg_zalloc_free_pool(MemPool **pmp)
+{
+    struct dbg_zalloc_pool *dzp;
+    struct dbg_zalloc_node *dzn;
+    int i;
+
+    if (*pmp == NULL)
+	return;
+    dzp = (*pmp)->mp_DzpPtr;
+
+    dbg_busy++;
+    __sync_synchronize();
+    for (i = 0; i < NODE_BUCKETS; i++) {
+	struct dbg_zalloc_node *next;
+	for (dzn = dzp->node[i]; dzn; dzn = next) {
+	    next = dzn->next;
+	    free(dzn);
+	}
+    }
+
+    *(dzp->pprevnext) = dzp->next;
+    if (dzp->next)
+	dzp->next->pprevnext = dzp->pprevnext;
+    __sync_synchronize();
+    dbg_busy--;
+    free(dzp);
+}
+
+#endif /* DEBUG_ZALLOC */
+
