Blame


1 9c635587 2004-06-09 devnull #include <u.h>
2 9c635587 2004-06-09 devnull #define NOPLAN9DEFINES
3 9c635587 2004-06-09 devnull #include <libc.h>
4 9c635587 2004-06-09 devnull
5 9c635587 2004-06-09 devnull /*
6 9c635587 2004-06-09 devnull * The Unix libc routines cannot be trusted to do their own locking.
7 9c635587 2004-06-09 devnull * Sad but apparently true.
8 9c635587 2004-06-09 devnull */
9 9c635587 2004-06-09 devnull static Lock malloclock;
10 9c635587 2004-06-09 devnull static int mallocpid;
11 9c635587 2004-06-09 devnull
12 9c635587 2004-06-09 devnull /*
13 9c635587 2004-06-09 devnull * The Unix mallocs don't do nearly enough error checking
14 9c635587 2004-06-09 devnull * for my tastes. We'll waste another 24 bytes per guy so that
15 9c635587 2004-06-09 devnull * we can. This is severely antisocial, since now free and p9free
16 9c635587 2004-06-09 devnull * are not interchangeable.
17 9c635587 2004-06-09 devnull */
18 9c635587 2004-06-09 devnull int debugmalloc;
19 9c635587 2004-06-09 devnull
20 9c635587 2004-06-09 devnull #define Overhead (debugmalloc ? (6*sizeof(ulong)) : 0)
21 9c635587 2004-06-09 devnull #define MallocMagic 0xA110C09
22 9c635587 2004-06-09 devnull #define ReallocMagic 0xB110C09
23 9c635587 2004-06-09 devnull #define CallocMagic 0xC110C09
24 9c635587 2004-06-09 devnull #define FreeMagic 0xF533F533
25 9c635587 2004-06-09 devnull #define CheckMagic 0
26 9c635587 2004-06-09 devnull #define END "\x7F\x2E\x55\x23"
27 9c635587 2004-06-09 devnull
28 9c635587 2004-06-09 devnull static void
29 9c635587 2004-06-09 devnull whoops(void *v)
30 9c635587 2004-06-09 devnull {
31 9c635587 2004-06-09 devnull fprint(2, "bad malloc block %p\n", v);
32 9c635587 2004-06-09 devnull abort();
33 9c635587 2004-06-09 devnull }
34 9c635587 2004-06-09 devnull
35 9c635587 2004-06-09 devnull static void*
36 9c635587 2004-06-09 devnull mark(void *v, ulong pc, ulong n, ulong magic)
37 9c635587 2004-06-09 devnull {
38 9c635587 2004-06-09 devnull ulong *u;
39 9c635587 2004-06-09 devnull char *p;
40 9c635587 2004-06-09 devnull
41 9c635587 2004-06-09 devnull if(!debugmalloc)
42 9c635587 2004-06-09 devnull return v;
43 9c635587 2004-06-09 devnull
44 9c635587 2004-06-09 devnull if(v == nil)
45 9c635587 2004-06-09 devnull return nil;
46 9c635587 2004-06-09 devnull
47 9c635587 2004-06-09 devnull if(magic == FreeMagic || magic == CheckMagic){
48 9c635587 2004-06-09 devnull u = (ulong*)((char*)v-4*sizeof(ulong));
49 9c635587 2004-06-09 devnull if(u[0] != MallocMagic && u[0] != ReallocMagic && u[0] != CallocMagic)
50 9c635587 2004-06-09 devnull whoops(v);
51 9c635587 2004-06-09 devnull n = u[1];
52 9c635587 2004-06-09 devnull p = (char*)v+n;
53 9c635587 2004-06-09 devnull if(memcmp(p, END, 4) != 0)
54 9c635587 2004-06-09 devnull whoops(v);
55 9c635587 2004-06-09 devnull if(magic != CheckMagic){
56 9c635587 2004-06-09 devnull u[0] = FreeMagic;
57 9c635587 2004-06-09 devnull u[1] = u[2] = u[3] = pc;
58 9c635587 2004-06-09 devnull if(n > 16){
59 9c635587 2004-06-09 devnull u[4] = u[5] = u[6] = u[7] = pc;
60 9c635587 2004-06-09 devnull memset((char*)v+16, 0xFB, n-16);
61 9c635587 2004-06-09 devnull }
62 9c635587 2004-06-09 devnull }
63 9c635587 2004-06-09 devnull return u;
64 9c635587 2004-06-09 devnull }else{
65 9c635587 2004-06-09 devnull u = v;
66 9c635587 2004-06-09 devnull u[0] = magic;
67 9c635587 2004-06-09 devnull u[1] = n;
68 9c635587 2004-06-09 devnull u[2] = 0;
69 9c635587 2004-06-09 devnull u[3] = 0;
70 9c635587 2004-06-09 devnull if(magic == ReallocMagic)
71 9c635587 2004-06-09 devnull u[3] = pc;
72 9c635587 2004-06-09 devnull else
73 9c635587 2004-06-09 devnull u[2] = pc;
74 9c635587 2004-06-09 devnull p = (char*)(u+4)+n;
75 9c635587 2004-06-09 devnull memmove(p, END, 4);
76 9c635587 2004-06-09 devnull return u+4;
77 9c635587 2004-06-09 devnull }
78 9c635587 2004-06-09 devnull }
79 9c635587 2004-06-09 devnull
80 9c635587 2004-06-09 devnull void
81 9c635587 2004-06-09 devnull setmalloctag(void *v, ulong t)
82 9c635587 2004-06-09 devnull {
83 9c635587 2004-06-09 devnull ulong *u;
84 9c635587 2004-06-09 devnull
85 9c635587 2004-06-09 devnull if(!debugmalloc)
86 9c635587 2004-06-09 devnull return;
87 9c635587 2004-06-09 devnull
88 9c635587 2004-06-09 devnull if(v == nil)
89 9c635587 2004-06-09 devnull return;
90 9c635587 2004-06-09 devnull u = mark(v, 0, 0, 0);
91 9c635587 2004-06-09 devnull u[2] = t;
92 9c635587 2004-06-09 devnull }
93 9c635587 2004-06-09 devnull
94 9c635587 2004-06-09 devnull void
95 9c635587 2004-06-09 devnull setrealloctag(void *v, ulong t)
96 9c635587 2004-06-09 devnull {
97 9c635587 2004-06-09 devnull ulong *u;
98 9c635587 2004-06-09 devnull
99 9c635587 2004-06-09 devnull if(!debugmalloc)
100 9c635587 2004-06-09 devnull return;
101 9c635587 2004-06-09 devnull
102 9c635587 2004-06-09 devnull if(v == nil)
103 9c635587 2004-06-09 devnull return;
104 9c635587 2004-06-09 devnull u = mark(v, 0, 0, 0);
105 9c635587 2004-06-09 devnull u[3] = t;
106 9c635587 2004-06-09 devnull }
107 9c635587 2004-06-09 devnull
108 9c635587 2004-06-09 devnull void*
109 9c635587 2004-06-09 devnull p9malloc(ulong n)
110 9c635587 2004-06-09 devnull {
111 9c635587 2004-06-09 devnull void *v;
112 9c635587 2004-06-09 devnull if(n == 0)
113 9c635587 2004-06-09 devnull n++;
114 cbeb0b26 2006-04-01 devnull /*fprint(2, "%s %d malloc\n", argv0, getpid()); */
115 9c635587 2004-06-09 devnull lock(&malloclock);
116 9c635587 2004-06-09 devnull mallocpid = getpid();
117 9c635587 2004-06-09 devnull v = malloc(n+Overhead);
118 9c635587 2004-06-09 devnull v = mark(v, getcallerpc(&n), n, MallocMagic);
119 9c635587 2004-06-09 devnull unlock(&malloclock);
120 cbeb0b26 2006-04-01 devnull /*fprint(2, "%s %d donemalloc\n", argv0, getpid()); */
121 9c635587 2004-06-09 devnull return v;
122 9c635587 2004-06-09 devnull }
123 9c635587 2004-06-09 devnull
124 9c635587 2004-06-09 devnull void
125 9c635587 2004-06-09 devnull p9free(void *v)
126 9c635587 2004-06-09 devnull {
127 9c635587 2004-06-09 devnull if(v == nil)
128 9c635587 2004-06-09 devnull return;
129 9c635587 2004-06-09 devnull
130 cbeb0b26 2006-04-01 devnull /*fprint(2, "%s %d free\n", argv0, getpid()); */
131 9c635587 2004-06-09 devnull lock(&malloclock);
132 9c635587 2004-06-09 devnull mallocpid = getpid();
133 9c635587 2004-06-09 devnull v = mark(v, getcallerpc(&v), 0, FreeMagic);
134 9c635587 2004-06-09 devnull free(v);
135 9c635587 2004-06-09 devnull unlock(&malloclock);
136 cbeb0b26 2006-04-01 devnull /*fprint(2, "%s %d donefree\n", argv0, getpid()); */
137 9c635587 2004-06-09 devnull }
138 9c635587 2004-06-09 devnull
139 9c635587 2004-06-09 devnull void*
140 9c635587 2004-06-09 devnull p9calloc(ulong a, ulong b)
141 9c635587 2004-06-09 devnull {
142 9c635587 2004-06-09 devnull void *v;
143 9c635587 2004-06-09 devnull
144 cbeb0b26 2006-04-01 devnull /*fprint(2, "%s %d calloc\n", argv0, getpid()); */
145 9c635587 2004-06-09 devnull lock(&malloclock);
146 9c635587 2004-06-09 devnull mallocpid = getpid();
147 9c635587 2004-06-09 devnull v = calloc(a*b+Overhead, 1);
148 9c635587 2004-06-09 devnull v = mark(v, getcallerpc(&a), a*b, CallocMagic);
149 9c635587 2004-06-09 devnull unlock(&malloclock);
150 cbeb0b26 2006-04-01 devnull /*fprint(2, "%s %d donecalloc\n", argv0, getpid()); */
151 9c635587 2004-06-09 devnull return v;
152 9c635587 2004-06-09 devnull }
153 9c635587 2004-06-09 devnull
154 9c635587 2004-06-09 devnull void*
155 9c635587 2004-06-09 devnull p9realloc(void *v, ulong n)
156 9c635587 2004-06-09 devnull {
157 cbeb0b26 2006-04-01 devnull /*fprint(2, "%s %d realloc\n", argv0, getpid()); */
158 9c635587 2004-06-09 devnull lock(&malloclock);
159 9c635587 2004-06-09 devnull mallocpid = getpid();
160 9c635587 2004-06-09 devnull v = mark(v, getcallerpc(&v), 0, CheckMagic);
161 9c635587 2004-06-09 devnull v = realloc(v, n+Overhead);
162 9c635587 2004-06-09 devnull v = mark(v, getcallerpc(&v), n, ReallocMagic);
163 9c635587 2004-06-09 devnull unlock(&malloclock);
164 cbeb0b26 2006-04-01 devnull /*fprint(2, "%s %d donerealloc\n", argv0, getpid()); */
165 9c635587 2004-06-09 devnull return v;
166 9c635587 2004-06-09 devnull }