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
# 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:
[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.
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
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
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 = \
--- /dev/null
+/* 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;
+}
#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;
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);
}