aboutsummaryrefslogtreecommitdiff
path: root/src/lib9
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2004-06-09 14:22:08 +0000
committerrsc <devnull@localhost>2004-06-09 14:22:08 +0000
commit9c635587071dcd7db349ec24ece1b397d24ac486 (patch)
treefcaf992109d4492e0ccf0a243b181850d7fbe3fa /src/lib9
parentf437e56d1d5c8180ee2f93273f78393426efd5f9 (diff)
downloadplan9port-9c635587071dcd7db349ec24ece1b397d24ac486.tar.gz
plan9port-9c635587071dcd7db349ec24ece1b397d24ac486.tar.bz2
plan9port-9c635587071dcd7db349ec24ece1b397d24ac486.zip
asdf
Diffstat (limited to 'src/lib9')
-rw-r--r--src/lib9/debugmalloc.c166
-rw-r--r--src/lib9/malloc.c43
2 files changed, 179 insertions, 30 deletions
diff --git a/src/lib9/debugmalloc.c b/src/lib9/debugmalloc.c
new file mode 100644
index 00000000..3958e243
--- /dev/null
+++ b/src/lib9/debugmalloc.c
@@ -0,0 +1,166 @@
+#include <u.h>
+#define NOPLAN9DEFINES
+#include <libc.h>
+
+/*
+ * The Unix libc routines cannot be trusted to do their own locking.
+ * Sad but apparently true.
+ */
+static Lock malloclock;
+static int mallocpid;
+
+/*
+ * The Unix mallocs don't do nearly enough error checking
+ * for my tastes. We'll waste another 24 bytes per guy so that
+ * we can. This is severely antisocial, since now free and p9free
+ * are not interchangeable.
+ */
+int debugmalloc;
+
+#define Overhead (debugmalloc ? (6*sizeof(ulong)) : 0)
+#define MallocMagic 0xA110C09
+#define ReallocMagic 0xB110C09
+#define CallocMagic 0xC110C09
+#define FreeMagic 0xF533F533
+#define CheckMagic 0
+#define END "\x7F\x2E\x55\x23"
+
+static void
+whoops(void *v)
+{
+ fprint(2, "bad malloc block %p\n", v);
+ abort();
+}
+
+static void*
+mark(void *v, ulong pc, ulong n, ulong magic)
+{
+ ulong *u;
+ char *p;
+
+ if(!debugmalloc)
+ return v;
+
+ if(v == nil)
+ return nil;
+
+ if(magic == FreeMagic || magic == CheckMagic){
+ u = (ulong*)((char*)v-4*sizeof(ulong));
+ if(u[0] != MallocMagic && u[0] != ReallocMagic && u[0] != CallocMagic)
+ whoops(v);
+ n = u[1];
+ p = (char*)v+n;
+ if(memcmp(p, END, 4) != 0)
+ whoops(v);
+ if(magic != CheckMagic){
+ u[0] = FreeMagic;
+ u[1] = u[2] = u[3] = pc;
+ if(n > 16){
+ u[4] = u[5] = u[6] = u[7] = pc;
+ memset((char*)v+16, 0xFB, n-16);
+ }
+ }
+ return u;
+ }else{
+ u = v;
+ u[0] = magic;
+ u[1] = n;
+ u[2] = 0;
+ u[3] = 0;
+ if(magic == ReallocMagic)
+ u[3] = pc;
+ else
+ u[2] = pc;
+ p = (char*)(u+4)+n;
+ memmove(p, END, 4);
+ return u+4;
+ }
+}
+
+void
+setmalloctag(void *v, ulong t)
+{
+ ulong *u;
+
+ if(!debugmalloc)
+ return;
+
+ if(v == nil)
+ return;
+ u = mark(v, 0, 0, 0);
+ u[2] = t;
+}
+
+void
+setrealloctag(void *v, ulong t)
+{
+ ulong *u;
+
+ if(!debugmalloc)
+ return;
+
+ if(v == nil)
+ return;
+ u = mark(v, 0, 0, 0);
+ u[3] = t;
+}
+
+void*
+p9malloc(ulong n)
+{
+ void *v;
+ if(n == 0)
+ n++;
+//fprint(2, "%s %d malloc\n", argv0, getpid());
+ lock(&malloclock);
+ mallocpid = getpid();
+ v = malloc(n+Overhead);
+ v = mark(v, getcallerpc(&n), n, MallocMagic);
+ unlock(&malloclock);
+//fprint(2, "%s %d donemalloc\n", argv0, getpid());
+ return v;
+}
+
+void
+p9free(void *v)
+{
+ if(v == nil)
+ return;
+
+//fprint(2, "%s %d free\n", argv0, getpid());
+ lock(&malloclock);
+ mallocpid = getpid();
+ v = mark(v, getcallerpc(&v), 0, FreeMagic);
+ free(v);
+ unlock(&malloclock);
+//fprint(2, "%s %d donefree\n", argv0, getpid());
+}
+
+void*
+p9calloc(ulong a, ulong b)
+{
+ void *v;
+
+//fprint(2, "%s %d calloc\n", argv0, getpid());
+ lock(&malloclock);
+ mallocpid = getpid();
+ v = calloc(a*b+Overhead, 1);
+ v = mark(v, getcallerpc(&a), a*b, CallocMagic);
+ unlock(&malloclock);
+//fprint(2, "%s %d donecalloc\n", argv0, getpid());
+ return v;
+}
+
+void*
+p9realloc(void *v, ulong n)
+{
+//fprint(2, "%s %d realloc\n", argv0, getpid());
+ lock(&malloclock);
+ mallocpid = getpid();
+ v = mark(v, getcallerpc(&v), 0, CheckMagic);
+ v = realloc(v, n+Overhead);
+ v = mark(v, getcallerpc(&v), n, ReallocMagic);
+ unlock(&malloclock);
+//fprint(2, "%s %d donerealloc\n", argv0, getpid());
+ return v;
+}
diff --git a/src/lib9/malloc.c b/src/lib9/malloc.c
index 7c5b1786..2c6731ea 100644
--- a/src/lib9/malloc.c
+++ b/src/lib9/malloc.c
@@ -1,58 +1,41 @@
-#include <u.h>
-#define NOPLAN9DEFINES
-#include <libc.h>
-
/*
- * The Unix libc routines cannot be trusted to do their own locking.
- * Sad but apparently true.
+ * These are here mainly so that I can link against
+ * debugmalloc.c instead and not recompile the world.
*/
-static Lock malloclock;
+#include <u.h>
+#define NOPLAN9DEFINES
+#include <libc.h>
void*
p9malloc(ulong n)
{
void *v;
+
if(n == 0)
n++;
-//fprint(2, "%s %d malloc\n", argv0, getpid());
- lock(&malloclock);
- v = malloc(n);
- unlock(&malloclock);
-//fprint(2, "%s %d donemalloc\n", argv0, getpid());
- return v;
+ return malloc(n);
}
void
p9free(void *v)
{
-//fprint(2, "%s %d free\n", argv0, getpid());
- lock(&malloclock);
+ if(v == nil)
+ return;
free(v);
- unlock(&malloclock);
-//fprint(2, "%s %d donefree\n", argv0, getpid());
}
void*
p9calloc(ulong a, ulong b)
{
- void *v;
+ if(a*b == 0)
+ a = b = 1;
-//fprint(2, "%s %d calloc\n", argv0, getpid());
- lock(&malloclock);
- v = calloc(a, b);
- unlock(&malloclock);
-//fprint(2, "%s %d donecalloc\n", argv0, getpid());
- return v;
+ return calloc(a*b, 1);
}
void*
p9realloc(void *v, ulong n)
{
-//fprint(2, "%s %d realloc\n", argv0, getpid());
- lock(&malloclock);
- v = realloc(v, n);
- unlock(&malloclock);
-//fprint(2, "%s %d donerealloc\n", argv0, getpid());
- return v;
+ return realloc(v, n);
}