changeset 41:ef8bedab8a4b

Add malloc debug code.
author David A. Holland
date Sat, 30 Mar 2013 21:50:37 -0400
parents 291fefe664f2
children ad7763329eba f185d1ac4db4
files utils.c
diffstat 1 files changed, 96 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/utils.c	Sat Mar 30 21:48:57 2013 -0400
+++ b/utils.c	Sat Mar 30 21:50:37 2013 -0400
@@ -29,10 +29,13 @@
 
 #include <stdlib.h>
 #include <string.h>
+#include <assert.h>
 #include <err.h>
 
 #include "utils.h"
 
+#define MALLOCDEBUG
+
 const char ws[] =
 	" \t\f\v"
 ;
@@ -43,40 +46,123 @@
 	"_"
 ;
 
+////////////////////////////////////////////////////////////
+// malloc
+
+#define ROUNDUP(len, size) ((size) * (((len) + (size) - 1) / (size)))
+
+#ifdef MALLOCDEBUG
+
+struct mallocheader {
+	struct mallocheader *self;
+	size_t len;
+};
+
+static
+size_t
+adjustsize(size_t len)
+{
+	const size_t sz = sizeof(struct mallocheader);
+	return ROUNDUP(len, sz) + 2*sz;
+}
+
+static
+void *
+placeheaders(void *block, size_t len)
+{
+	struct mallocheader *bothdr, *tophdr;
+	size_t roundedlen;
+	void *ret;
+
+	roundedlen = ROUNDUP(len, sizeof(struct mallocheader));
+	bothdr = block;
+	bothdr->len = len;
+	bothdr->self = block;
+	ret = bothdr + 1;
+	tophdr = (void *)(((unsigned char *)ret) + roundedlen);
+	tophdr->len = len;
+	tophdr->self = bothdr;
+	return ret;
+}
+
+static
+void *
+checkheaders(void *block, size_t len)
+{
+	struct mallocheader *bothdr, *tophdr;
+	size_t roundedlen;
+
+	if (block == NULL) {
+		assert(len == 0);
+		return block;
+	}
+
+	roundedlen = ROUNDUP(len, sizeof(struct mallocheader));
+	bothdr = block;
+	bothdr--;
+	assert(bothdr->self == bothdr);
+	assert(bothdr->len == len);
+	tophdr = (void *)(((unsigned char *)(bothdr + 1)) + roundedlen);
+	assert(tophdr->self == bothdr);
+	assert(tophdr->len == len);
+	return bothdr;
+}
+
+#else
+
+#define adjustsize(len) (len)
+#define placeheaders(block, len) ((void)(len), (block))
+#define checkheaders(ptr, len) ((void)(len), (ptr))
+
+#endif /* MALLOCDEBUG */
+
 void *
 domalloc(size_t len)
 {
 	void *ret;
+	size_t blocklen;
 
-	ret = malloc(len);
+	blocklen = adjustsize(len);
+	ret = malloc(blocklen);
 	if (ret == NULL) {
 		warnx("Out of memory");
 		die();
 	}
-	return ret;
+
+	return placeheaders(ret, len);
 }
 
 void *
 dorealloc(void *ptr, size_t oldlen, size_t newlen)
 {
 	void *ret;
+	void *blockptr;
+	size_t newblocklen;
 
-	(void)oldlen;
-	ret = realloc(ptr, newlen);
+	blockptr = checkheaders(ptr, oldlen);
+	newblocklen = adjustsize(newlen);
+
+	ret = realloc(blockptr, newblocklen);
 	if (ret == NULL) {
 		warnx("Out of memory");
 		die();
 	}
-	return ret;
+
+	return placeheaders(ret, newlen);
 }
 
 void
 dofree(void *ptr, size_t len)
 {
-	(void)len;
-	free(ptr);
+	void *blockptr;
+
+	blockptr = checkheaders(ptr, len);
+	free(blockptr);
 }
 
+////////////////////////////////////////////////////////////
+// string allocators
+
 char *
 dostrdup(const char *s)
 {
@@ -133,6 +219,9 @@
 	dofree(s, strlen(s)+1);
 }
 
+////////////////////////////////////////////////////////////
+// other stuff
+
 size_t
 notrailingws(char *buf, size_t len)
 {