16 struct allocation *next;
20 static struct allocation *alist, *atail;
22 static void init_once(void)
24 static int init_once_done;
31 static FILE *openlog(void)
33 if(logfile) return logfile;
34 return (logfile = fopen("chk.log", "a"));
37 static void closelog(void)
43 static void mark_alloc(struct allocation *a)
45 uintptr_t *left, *right, *end;
47 left = (uintptr_t*)(a + 1);
48 right = (uintptr_t*)((char*)a + a->fullsz) - 1;
49 end = (uintptr_t*)(a->ptr + a->sz);
51 while(left + 1 < (void*)a->ptr) {
52 *left = (uintptr_t)left;
56 *right = (uintptr_t)right;
61 static int check_alloc(struct allocation *a, const char *reason)
64 uintptr_t *left = (uintptr_t*)(a + 1);
65 uintptr_t *right = (uintptr_t*)((char*)a + a->fullsz) - 1;
66 void *end = a->ptr + a->sz;
67 int trash_left = 0, trash_right = 0;
68 char *last_trash_left = 0, *first_trash_right = 0;
69 char *first_trash_left = 0, *last_trash_right = 0;
72 if(!openlog()) return -1;
74 while(left + 1 < (void*)a->ptr) {
75 if(*left != (uintptr_t)left) {
76 fprintf(logfile, "@%p: %p\n", left, (void*)*left);
78 for(i=0; i<sizeof *left; i++) {
80 if(((*left >> s) & 0xff) != (((uintptr_t)left >> s) & 0xff)) {
81 if(!first_trash_left) first_trash_left = (char*)left;
83 last_trash_left = (char*)left + i;
89 if(*right != (uintptr_t)right) {
90 fprintf(logfile, "@%p: %p\n", right, (void*)*right);
92 for(i=0; i<sizeof *right; i++) {
94 if(((*right >> s) & 0xff) != (((uintptr_t)right >> s) & 0xff)) {
95 if(!last_trash_right) last_trash_right = (char*)right;
97 first_trash_right = (char*)right + i;
103 if(!(trash_left | trash_right)) return 0;
105 fprintf(logfile, "corrupted memory allocated from: %s:%d\n", a->file, a->lineno);
107 fprintf(logfile, " %d bytes at offset %d before start (%p)\n",
108 (int)(last_trash_left - first_trash_left),
109 (int)(a->ptr - last_trash_left), a->ptr);
112 fprintf(logfile, " %d bytes at offset %d after end (%p)\n",
113 (int)(last_trash_right - first_trash_right),
114 (int)(first_trash_right - end), end);
116 fprintf(logfile, " check due to %s\n", reason);
123 struct allocation *anode = alist;
125 check_alloc(anode, "explicit check call");
130 void *chk_malloc_impl(int sz, char *file, int line)
133 struct allocation *a;
137 fullsz = sz + OFFSET * 2;
138 if(!(a = malloc(fullsz))) {
142 a->ptr = (char*)a + OFFSET;
159 fprintf(logfile, "alloc(%d) from %s:%d\n", sz, a->file, a->lineno);
165 void *chk_realloc_impl(void *ptr, int sz, char *file, int line)
168 struct allocation *newptr;
169 struct allocation *a = (struct allocation*)((char*)ptr - OFFSET);
170 struct allocation *prev, dummy;
174 check_alloc(a, "realloc");
177 fullsz = sz + OFFSET * 2;
178 if(!(newptr = realloc(a, fullsz))) {
185 if(prev->next == a) {
194 a->ptr = (char*)a + OFFSET;
203 fprintf(logfile, "realloc(%d) from %s:%d\n", sz, a->file, a->lineno);
209 void chk_free(void *p)
211 struct allocation dummy, *prev, *a;
217 a = (struct allocation*)((char*)p - OFFSET);
219 fprintf(logfile, "free() %d allocated from %s:%d\n", a->sz, a->file, a->lineno);
226 if(prev->next->ptr == p) {
228 prev->next = a->next;
230 check_alloc(a, "free");
239 #endif /* CHECK_ALLOC */