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