Add built-in debug malloc wrapper.
authorMichael Poole <mdpoole@troilus.org>
Thu, 20 Jan 2005 23:41:17 +0000 (23:41 +0000)
committerMichael Poole <mdpoole@troilus.org>
Thu, 20 Jan 2005 23:41:17 +0000 (23:41 +0000)
TODO: Remove the completed TODO item.

configure.in: Add --with-malloc=srvx support.

src/Makefile.am: Add alloc-srvx.c to extra sources.

src/common.h: Reindent debug malloc directives; add directives for
WITH_MALLOC_SRVX.

src/dict-splay.c: Kludge around free() as macro vs function.
git-archimport-id: srvx@srvx.net--2005-srvx/srvx--devo--1.3--patch-4

ChangeLog
TODO
configure.in
src/Makefile.am
src/alloc-srvx.c [new file with mode: 0644]
src/common.h
src/dict-splay.c

index 4f254831d5aff51a7387319f8188074db8a82e79..518bff5bec1282bab28f570f6c11728ffd7d77a3 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,32 @@
 # arch-tag: automatic-ChangeLog--srvx@srvx.net--2005-srvx/srvx--devo--1.3
 #
 
+2005-01-20 23:41:17 GMT        Michael Poole <mdpoole@troilus.org>     patch-4
+
+    Summary:
+      Add built-in debug malloc wrapper.
+    Revision:
+      srvx--devo--1.3--patch-4
+
+    TODO: Remove the completed TODO item.
+    
+    configure.in: Add --with-malloc=srvx support.
+    
+    src/Makefile.am: Add alloc-srvx.c to extra sources.
+    
+    src/common.h: Reindent debug malloc directives; add directives for
+    WITH_MALLOC_SRVX.
+    
+    src/dict-splay.c: Kludge around free() as macro vs function.
+
+    new files:
+     src/.arch-ids/alloc-srvx.c.id src/alloc-srvx.c
+
+    modified files:
+     ChangeLog TODO configure.in src/Makefile.am src/common.h
+     src/dict-splay.c
+
+
 2005-01-20 22:51:54 GMT        Michael Poole <mdpoole@troilus.org>     patch-3
 
     Summary:
diff --git a/TODO b/TODO
index fdda819d54d9bf16e238a055386cd6a9cfa96b09..cc40e98a5d30272872dea86d00f14508bb4b449b 100644 (file)
--- a/TODO
+++ b/TODO
@@ -18,6 +18,3 @@
 [FEATREQ] Suspension durations and/or comments when suspending user access to a channel
 
 [FEATREQ] support "unregistered": ?ctrace print mode +s unregistered
-
-- rewrite memory allocation calls to use wrapper macros, and add
-  optional debugging for the stubs to tag size and/or type.
index 26ef7dd08e71511e2bdd62c4fcdbfdba63800ce2..81dd91dc3bff4a7836f14ae3062215a7c56ad981 100644 (file)
@@ -152,7 +152,7 @@ dnl Optional features.
 AC_MSG_CHECKING(which malloc to use)
 AC_ARG_WITH(malloc,
 [  --with-malloc=type      Enables use of a special malloc library; one of:
-                          system (the default), boehm-gc, dmalloc, mpatrol],
+                          system (the default), boehm-gc, dmalloc, mpatrol, srvx],
 [],
 [withval="system"])
 if test "x$withval" = "xsystem" ; then
@@ -176,6 +176,10 @@ elif test "x$withval" = "xboehm-gc" ; then
   AC_CHECK_LIB(dl, dlopen, , AC_MSG_ERROR([libdl library is missing.  boehm-gc build will fail.]))
   AC_CHECK_LIB(gc, GC_gcollect, , AC_MSG_ERROR([Boehm GC library is missing.  boehm-gc build will fail.]))
   AC_DEFINE(WITH_MALLOC_BOEHM_GC, 1, [Define if using the Boehm GC to garbage collect and check memory leaks])
+elif test "x$withval" = "xsrvx" ; then
+  AC_MSG_RESULT(srvx)
+  AC_DEFINE(WITH_MALLOC_SRVX, 1, [Define if using the srvx internal debug allocator])
+  MODULE_OBJS="$MODULE_OBJS alloc-srvx.\$(OBJEXT)"
 else
   AC_MSG_ERROR([Unknown malloc type $withval])
 fi
index f605f8632aff520f6c4029d23274c64420c64885..7fe7c1d12f8ecf40389242d41725d00eebec14f8 100644 (file)
@@ -22,7 +22,7 @@ checkversion:
            mv $$TMPFILE arch-version.h ; \
        fi
 
-EXTRA_srvx_SOURCES = proto-bahamut.c proto-common.c proto-p10.c mod-snoop.c mod-memoserv.c mod-helpserv.c mod-sockcheck.c
+EXTRA_srvx_SOURCES = alloc-srvx.c proto-bahamut.c proto-common.c proto-p10.c mod-snoop.c mod-memoserv.c mod-helpserv.c mod-sockcheck.c
 srvx_LDADD = @MODULE_OBJS@
 srvx_DEPENDENCIES = @MODULE_OBJS@
 srvx_SOURCES = \
diff --git a/src/alloc-srvx.c b/src/alloc-srvx.c
new file mode 100644 (file)
index 0000000..91d9035
--- /dev/null
@@ -0,0 +1,128 @@
+/* alloc-srvx.c - Debug allocation wrapper
+ * Copyright 2005 srvx Development Team
+ *
+ * This file is part of srvx.
+ *
+ * srvx is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include "common.h"
+
+#undef malloc
+#undef free
+
+/* cookies for anybody who recognizes these bytes without help :) */
+#define ALLOC_MAGIC 0x1acf
+#define FREE_MAGIC  0xfc1d
+
+struct alloc_header {
+    unsigned int file_id : 8;
+    unsigned int size : 24;
+    unsigned int line : 16;
+    unsigned int magic : 16;
+};
+
+static char file_id_map[256][32];
+static unsigned int file_ids_used;
+
+static int
+file_id_cmp(const void *a_, const void *b_)
+{
+    return strcmp(a_, b_);
+}
+
+static unsigned int
+get_file_id(const char *fname)
+{
+    void *entry;
+
+    entry = bsearch(fname, file_id_map, file_ids_used, sizeof(file_id_map[0]), file_id_cmp);
+    if (entry)
+        return ((char*)entry - file_id_map[0]) / sizeof(file_id_map[0]);
+    strcpy(file_id_map[file_ids_used++], fname);
+    qsort(file_id_map, file_ids_used, sizeof(file_id_map[0]), file_id_cmp);
+    return file_ids_used - 1;
+}
+
+void *
+srvx_malloc(const char *file, unsigned int line, size_t size)
+{
+    struct alloc_header *block;
+
+    block = malloc(sizeof(*block) + size);
+    assert(block != NULL);
+    memset(block, 0, sizeof(*block) + size);
+    block->file_id = get_file_id(file);
+    block->line = line;
+    block->size = size;
+    block->magic = ALLOC_MAGIC;
+    return block + 1;
+}
+
+void *
+srvx_realloc(const char *file, unsigned int line, void *ptr, size_t size)
+{
+    struct alloc_header *block = NULL, *newblock;
+
+    if (ptr) {
+        block = (struct alloc_header *)ptr - 1;
+        assert(block->magic == ALLOC_MAGIC);
+        if (block->size >= size)
+            return block + 1;
+    }
+
+    newblock = malloc(sizeof(*newblock) + size);
+    assert(newblock != NULL);
+    memset(newblock, 0, sizeof(*newblock) + size);
+    newblock->file_id = get_file_id(file);
+    newblock->line = line;
+    newblock->size = size;
+    newblock->magic = ALLOC_MAGIC;
+
+    if (ptr) {
+        memcpy(newblock + 1, block + 1, block->size);
+        size = block->size + sizeof(*block);
+        memset(block, 0, size);
+        block->magic = FREE_MAGIC;
+        free(block);
+    }
+
+    return newblock + 1;
+}
+
+char *
+srvx_strdup(const char *file, unsigned int line, const char *src)
+{
+    char *target;
+    size_t len;
+
+    len = strlen(src) + 1;
+    target = srvx_malloc(file, line, len);
+    memcpy(target, src, len);
+    return target;
+}
+
+void
+srvx_free(const char *file, unsigned int line, void *ptr)
+{
+    struct alloc_header *block;
+    size_t size;
+
+    if (!ptr)
+        return;
+    block = (struct alloc_header *)ptr - 1;
+    assert(block->magic == ALLOC_MAGIC);
+    size = block->size + sizeof(*block);
+    memset(block, 0, size);
+    block->magic = FREE_MAGIC;
+    free(block);
+    (void)file; (void)line;
+}
index 952b1de056e85cc90241ac82eae7f3fd03a0b6e9..a8458a37db958e7e0ffdeff166589334a55b961d 100644 (file)
@@ -64,25 +64,40 @@ extern struct tm *localtime_r(const time_t *clock, struct tm *res);
 #endif
 
 #if defined(WITH_MALLOC_DMALLOC)
-#define DMALLOC_FUNC_CHECK 1
-#include <string.h>
-#include <dmalloc.h>
+# define DMALLOC_FUNC_CHECK 1
+# include <string.h>
+# include <dmalloc.h>
 #elif defined(WITH_MALLOC_MPATROL)
-#include <string.h>
-#include <mpatrol.h>
+# include <string.h>
+# include <mpatrol.h>
 #elif defined(WITH_MALLOC_BOEHM_GC)
-#if !defined(NDEBUG)
-#define GC_DEBUG 1
-#endif
-#include <stdlib.h>
-#include <string.h>
-#include <gc/gc.h>
-#define malloc(n) GC_MALLOC(n)
-#define calloc(m,n) GC_MALLOC((m)*(n))
-#define realloc(p,n) GC_REALLOC((p),(n))
-#define free(p) GC_FREE(p)
-#undef  HAVE_STRDUP
-#undef strdup
+# if !defined(NDEBUG)
+#  define GC_DEBUG 1
+# endif
+# include <stdlib.h>
+# include <string.h>
+# include <gc/gc.h>
+# define malloc(n) GC_MALLOC(n)
+# define calloc(m,n) GC_MALLOC((m)*(n))
+# define realloc(p,n) GC_REALLOC((p),(n))
+# define free(p) GC_FREE(p)
+# undef  HAVE_STRDUP
+# undef strdup
+#elif defined(WITH_MALLOC_SRVX)
+# undef malloc
+# define malloc(n) srvx_malloc(__FILE__, __LINE__, (n))
+# undef calloc
+# define calloc(m,n) srvx_malloc(__FILE__, __LINE__, (m)*(n))
+# undef realloc
+# define realloc(p,n) srvx_realloc(__FILE__, __LINE__, (p), (n))
+# undef free
+# define free(p) srvx_free(__FILE__, __LINE__, (p))
+# undef strdup
+# define strdup(s) srvx_strdup(__FILE__, __LINE__, (s))
+extern void *srvx_malloc(const char *, unsigned int, size_t);
+extern void *srvx_realloc(const char *, unsigned int, void *, size_t);
+extern char *srvx_strdup(const char *, unsigned int, const char *);
+extern void srvx_free(const char *, unsigned int, void *);
 #endif
 
 extern time_t now;
index 42bb9025778342b5107b190ee4f70cc0ac04b55c..4619ce562dc7ea516b5c4bc6fbe1705487818755 100644 (file)
@@ -123,10 +123,18 @@ dict_splay(struct dict_node *node, const char *key)
 static void
 dict_dispose_node(struct dict_node *node, free_f free_keys, free_f free_data)
 {
-    if (free_keys && node->key)
-        free_keys((void*)node->key);
-    if (free_data && node->data)
-        free_data(node->data);
+    if (free_keys && node->key) {
+        if (free_keys == free)
+            free((void*)node->key);
+        else
+            free_keys((void*)node->key);
+    }
+    if (free_data && node->data) {
+        if (free_data == free)
+            free(node->data);
+        else
+            free_data(node->data);
+    }
     free(node);
 }