Add redzone and statistics reporting to debug allocator.
authorMichael Poole <mdpoole@troilus.org>
Fri, 21 Jan 2005 00:48:35 +0000 (00:48 +0000)
committerMichael Poole <mdpoole@troilus.org>
Fri, 21 Jan 2005 00:48:35 +0000 (00:48 +0000)
src/alloc-srvx.c (redzone): New variable to detect buffer overwrites.
(alloc_count, alloc_size): New variables to track allocation stats.
(srvx_malloc, srvx_realloc, srvx_free): Use the above.

src/opserv.c (OSMSG_STATS_MEMORY): New translation string.
(cmd_stats_memory): New (conditional) command function.
(init_opserv): Conditionally provide cmd_stats_memory.
git-archimport-id: srvx@srvx.net--2005-srvx/srvx--devo--1.3--patch-5

ChangeLog
src/alloc-srvx.c
src/opserv.c

index 518bff5bec1282bab28f570f6c11728ffd7d77a3..26989642f2a10902e1dcaada606aa0c92d8bb09f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,25 @@
 # arch-tag: automatic-ChangeLog--srvx@srvx.net--2005-srvx/srvx--devo--1.3
 #
 
+2005-01-21 00:48:35 GMT        Michael Poole <mdpoole@troilus.org>     patch-5
+
+    Summary:
+      Add redzone and statistics reporting to debug allocator.
+    Revision:
+      srvx--devo--1.3--patch-5
+
+    src/alloc-srvx.c (redzone): New variable to detect buffer overwrites.
+    (alloc_count, alloc_size): New variables to track allocation stats.
+    (srvx_malloc, srvx_realloc, srvx_free): Use the above.
+    
+    src/opserv.c (OSMSG_STATS_MEMORY): New translation string.
+    (cmd_stats_memory): New (conditional) command function.
+    (init_opserv): Conditionally provide cmd_stats_memory.
+
+    modified files:
+     ChangeLog src/alloc-srvx.c src/opserv.c
+
+
 2005-01-20 23:41:17 GMT        Michael Poole <mdpoole@troilus.org>     patch-4
 
     Summary:
index 91d9035d2ecd2a4aa7cc154786c18d3ab285527d..b8e1afab34cc18680d8f344b8a1c3df0b971d428 100644 (file)
@@ -22,6 +22,7 @@
 /* cookies for anybody who recognizes these bytes without help :) */
 #define ALLOC_MAGIC 0x1acf
 #define FREE_MAGIC  0xfc1d
+const char redzone[] = { '\x03', '\x47', '\x76', '\xc7' };
 
 struct alloc_header {
     unsigned int file_id : 8;
@@ -32,6 +33,7 @@ struct alloc_header {
 
 static char file_id_map[256][32];
 static unsigned int file_ids_used;
+unsigned long alloc_count, alloc_size;
 
 static int
 file_id_cmp(const void *a_, const void *b_)
@@ -57,13 +59,16 @@ srvx_malloc(const char *file, unsigned int line, size_t size)
 {
     struct alloc_header *block;
 
-    block = malloc(sizeof(*block) + size);
+    block = malloc(sizeof(*block) + size + sizeof(redzone));
     assert(block != NULL);
     memset(block, 0, sizeof(*block) + size);
+    memcpy((char*)(block + 1) + size, redzone, sizeof(redzone));
     block->file_id = get_file_id(file);
     block->line = line;
     block->size = size;
     block->magic = ALLOC_MAGIC;
+    alloc_count++;
+    alloc_size += size;
     return block + 1;
 }
 
@@ -75,17 +80,21 @@ srvx_realloc(const char *file, unsigned int line, void *ptr, size_t size)
     if (ptr) {
         block = (struct alloc_header *)ptr - 1;
         assert(block->magic == ALLOC_MAGIC);
+        assert(0 == memcmp((char*)(block + 1) + block->size, redzone, sizeof(redzone)));
         if (block->size >= size)
             return block + 1;
     }
 
-    newblock = malloc(sizeof(*newblock) + size);
+    newblock = malloc(sizeof(*newblock) + size + sizeof(redzone));
     assert(newblock != NULL);
-    memset(newblock, 0, sizeof(*newblock) + size);
+    memset(newblock, 0, sizeof(*newblock) + size + sizeof(redzone));
+    memcpy((char*)(newblock + 1) + size, redzone, sizeof(redzone));
     newblock->file_id = get_file_id(file);
     newblock->line = line;
     newblock->size = size;
     newblock->magic = ALLOC_MAGIC;
+    alloc_count++;
+    alloc_size += size;
 
     if (ptr) {
         memcpy(newblock + 1, block + 1, block->size);
@@ -93,6 +102,8 @@ srvx_realloc(const char *file, unsigned int line, void *ptr, size_t size)
         memset(block, 0, size);
         block->magic = FREE_MAGIC;
         free(block);
+        alloc_count--;
+        alloc_size -= size - sizeof(*block);
     }
 
     return newblock + 1;
@@ -120,9 +131,12 @@ srvx_free(const char *file, unsigned int line, void *ptr)
         return;
     block = (struct alloc_header *)ptr - 1;
     assert(block->magic == ALLOC_MAGIC);
+    assert(0 == memcmp((char*)(block + 1) + block->size, redzone, sizeof(redzone)));
     size = block->size + sizeof(*block);
     memset(block, 0, size);
     block->magic = FREE_MAGIC;
     free(block);
+    alloc_count--;
+    alloc_size -= size - sizeof(*block);
     (void)file; (void)line;
 }
index f8b50760025f0323668c5ac8851409a664db6465..041a89a0d3b189bbda4003a4c5a756383de09c40 100644 (file)
@@ -228,6 +228,7 @@ static const struct message_entry msgtab[] = {
     { "OSMSG_WARN_LISTSTART", "Channel activity warnings:" },
     { "OSMSG_WARN_LISTENTRY", "%s (%s)" },
     { "OSMSG_WARN_LISTEND", "End of activity warning list." },
+    { "OSMSG_STATS_MEMORY", "%u allocations totalling %u bytes." },
     { "OSMSG_UPLINK_CONNECTING", "Establishing connection with %s (%s:%d)." },
     { "OSMSG_CURRENT_UPLINK", "$b%s$b is already the current uplink." },
     { "OSMSG_INVALID_UPLINK", "$b%s$b is not a valid uplink name." },
@@ -1578,6 +1579,14 @@ static MODCMD_FUNC(cmd_stats_warn) {
     return 1;
 }
 
+#if defined(WITH_MALLOC_SRVX)
+static MODCMD_FUNC(cmd_stats_memory) {
+    extern unsigned long alloc_count, alloc_size;
+    reply("OSMSG_STATS_MEMORY", alloc_count, alloc_size);
+    return 1;
+}
+#endif
+
 static MODCMD_FUNC(cmd_dump)
 {
     char linedup[MAXLEN], *original;
@@ -4101,6 +4110,9 @@ init_opserv(const char *nick)
     opserv_define_func("STATS UPLINK", cmd_stats_uplink, 0, 0, 0);
     opserv_define_func("STATS UPTIME", cmd_stats_uptime, 0, 0, 0);
     opserv_define_func("STATS WARN", cmd_stats_warn, 0, 0, 0);
+#if defined(WITH_MALLOC_SRVX)
+    opserv_define_func("STATS MEMORY", cmd_stats_memory, 0, 0, 0);
+#endif
     opserv_define_func("TRACE", cmd_trace, 100, 0, 3);
     opserv_define_func("TRACE PRINT", NULL, 0, 0, 0);
     opserv_define_func("TRACE COUNT", NULL, 0, 0, 0);