2 * Part: Memory management framework. This framework is used to
3 * find any memory leak.
5 * Version: $Id: memory.c,v 1.1.11 2005/03/01 01:22:13 acassen Exp $
7 * Authors: Alexandre Cassen, <acassen@linux-vs.org>
8 * Jan Holmberg, <jan@artech.net>
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 * See the GNU General Public License for more details.
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version
18 * 2 of the License, or (at your option) any later version.
20 * Copyright (C) 2001-2005 Alexandre Cassen, <acassen@linux-vs.org>
27 * Memory management. in debug mode,
28 * help finding eventual memory leak.
29 * Allocation memory types manipulated are :
31 * +type+--------meaning--------+
35 * ! 3 ! realloc null !
36 * ! 4 ! Not previus allocated !
37 * ! 8 ! Last free list !
39 * +----+-----------------------+
41 * global variabel debug bit 9 ( 512 ) used to
42 * flag some memory error.
58 /* Last free pointers */
59 static MEMCHECK free_list[256];
61 static MEMCHECK alloc_list[MAX_ALLOC_LIST];
62 static int number_alloc_list = 0;
63 static int n = 0; /* Alloc list pointer */
64 static int f = 0; /* Free list pointer */
67 dbg_malloc(unsigned long size, char *file, char *function, int line)
73 buf = zalloc(size + sizeof (long));
75 check = 0xa5a5 + size;
76 *(long *) ((char *) buf + size) = check;
78 while (i < number_alloc_list) {
79 if (alloc_list[i].type == 0)
84 if (i == number_alloc_list)
87 assert(number_alloc_list < MAX_ALLOC_LIST);
89 alloc_list[i].ptr = buf;
90 alloc_list[i].size = size;
91 alloc_list[i].file = file;
92 alloc_list[i].func = function;
93 alloc_list[i].line = line;
94 alloc_list[i].csum = check;
95 alloc_list[i].type = 9;
98 printf("zalloc[%3d:%3d], %p, %4ld at %s, %3d, %s\n",
99 i, number_alloc_list, buf, size, file, line,
107 dbg_strdup(char *str, char *file, char *function, int line)
114 size = strlen(str) + 1;
115 buf = zalloc(size + sizeof (long));
118 check = 0xa5a5 + size;
119 *(long *) ((char *) buf + size) = check;
121 while (i < number_alloc_list) {
122 if (alloc_list[i].type == 0)
127 if (i == number_alloc_list)
130 assert(number_alloc_list < MAX_ALLOC_LIST);
132 alloc_list[i].ptr = buf;
133 alloc_list[i].size = size;
134 alloc_list[i].file = file;
135 alloc_list[i].func = function;
136 alloc_list[i].line = line;
137 alloc_list[i].csum = check;
138 alloc_list[i].type = 9;
141 printf("strdup[%3d:%3d], %p, %4ld at %s, %3d, %s\n",
142 i, number_alloc_list, buf, size, file, line,
151 /* Display a buffer into a HEXA formatted output */
153 dump_buffer(char *buff, int count)
159 c = count + (16 - count % 16);
163 for (i = 0; i < c; i++) {
166 printf("%.4x ", i & 0xffff);
169 printf("%3.2x", buff[i] & 0xff);
172 if (!((i + 1) % 8)) {
177 for (j = i - 15; j <= i; j++)
179 if ((buff[j] & 0xff) >= 0x20
180 && (buff[j] & 0xff) <= 0x7e)
195 dbg_free(void *buffer, char *file, char *function, int line)
200 /* If nullpointer remember */
201 if (buffer == NULL) {
202 i = number_alloc_list++;
204 assert(number_alloc_list < MAX_ALLOC_LIST);
206 alloc_list[i].ptr = buffer;
207 alloc_list[i].size = 0;
208 alloc_list[i].file = file;
209 alloc_list[i].func = function;
210 alloc_list[i].line = line;
211 alloc_list[i].type = 2;
213 printf("free NULL in %s, %3d, %s\n", file,
216 debug |= 512; /* Memory Error detect */
222 while (i < number_alloc_list) {
223 if (alloc_list[i].type == 9 && alloc_list[i].ptr == buf) {
225 ((long *) ((char *) alloc_list[i].ptr +
226 alloc_list[i].size)) ==
228 alloc_list[i].type = 0; /* Release */
230 alloc_list[i].type = 1; /* Overrun */
232 printf("free corrupt, buffer overrun [%3d:%3d], %p, %4ld at %s, %3d, %s\n",
233 i, number_alloc_list,
234 buf, alloc_list[i].size, file,
236 dump_buffer(alloc_list[i].ptr,
237 alloc_list[i].size + sizeof (long));
238 printf("Check_sum\n");
239 dump_buffer((char *) &alloc_list[i].csum,
242 debug |= 512; /* Memory Error detect */
251 if (i == number_alloc_list) {
252 printf("Free ERROR %p\n", buffer);
255 assert(number_alloc_list < MAX_ALLOC_LIST);
257 alloc_list[i].ptr = buf;
258 alloc_list[i].size = 0;
259 alloc_list[i].file = file;
260 alloc_list[i].func = function;
261 alloc_list[i].line = line;
262 alloc_list[i].type = 4;
272 printf("free [%3d:%3d], %p, %4ld at %s, %3d, %s\n",
273 i, number_alloc_list, buf,
274 alloc_list[i].size, file, line, function);
276 free_list[f].file = file;
277 free_list[f].line = line;
278 free_list[f].func = function;
279 free_list[f].ptr = buffer;
280 free_list[f].type = 8;
281 free_list[f].csum = i; /* Using this field for row id */
291 dbg_free_final(char *banner)
293 unsigned int sum = 0, overrun = 0, badptr = 0;
297 printf("\n---[ Memory dump for (%s)]---\n\n", banner);
299 while (i < number_alloc_list) {
300 switch (alloc_list[i].type) {
304 ("null pointer to realloc(nil,%ld)! at %s, %3d, %s\n",
305 alloc_list[i].size, alloc_list[i].file,
306 alloc_list[i].line, alloc_list[i].func);
311 ("pointer not found in table to free(%p) [%3d:%3d], at %s, %3d, %s\n",
312 alloc_list[i].ptr, i, number_alloc_list,
313 alloc_list[i].file, alloc_list[i].line,
315 for (j = 0; j < 256; j++)
316 if (free_list[j].ptr == alloc_list[i].ptr)
317 if (free_list[j].type == 8)
319 (" -> pointer already released at [%3d:%3d], at %s, %3d, %s\n",
320 (int) free_list[j].csum,
328 printf("null pointer to free(nil)! at %s, %3d, %s\n",
329 alloc_list[i].file, alloc_list[i].line,
334 printf("%p [%3d:%3d], %4ld buffer overrun!:\n",
335 alloc_list[i].ptr, i, number_alloc_list,
337 printf(" --> source of malloc: %s, %3d, %s\n",
338 alloc_list[i].file, alloc_list[i].line,
342 sum += alloc_list[i].size;
343 printf("%p [%3d:%3d], %4ld not released!:\n",
344 alloc_list[i].ptr, i, number_alloc_list,
346 printf(" --> source of malloc: %s, %3d, %s\n",
347 alloc_list[i].file, alloc_list[i].line,
354 printf("\n\n---[ Memory dump summary for (%s) ]---\n", banner);
355 printf("Total number of bytes not freed...: %d\n", sum);
356 printf("Number of entries not freed.......: %d\n", n);
357 printf("Maximum allocated entries.........: %d\n", number_alloc_list);
358 printf("Number of bad entries.............: %d\n", badptr);
359 printf("Number of buffer overrun..........: %d\n\n", overrun);
361 if (sum || n || badptr || overrun)
362 printf("=> Program seems to have some memory problem !!!\n\n");
364 printf("=> Program seems to be memory allocation safe...\n\n");
368 dbg_realloc(void *buffer, unsigned long size, char *file, char *function,
375 if (buffer == NULL) {
376 printf("realloc %p %s, %3d %s\n", buffer, file, line, function);
377 i = number_alloc_list++;
379 assert(number_alloc_list < MAX_ALLOC_LIST);
381 alloc_list[i].ptr = NULL;
382 alloc_list[i].size = 0;
383 alloc_list[i].file = file;
384 alloc_list[i].func = function;
385 alloc_list[i].line = line;
386 alloc_list[i].type = 3;
387 return dbg_malloc(size, file, function, line);
392 while (i < number_alloc_list) {
393 if (alloc_list[i].ptr == buf) {
394 buf = alloc_list[i].ptr;
401 if (i == number_alloc_list) {
402 printf("realloc ERROR no matching zalloc %p \n", buffer);
405 assert(number_alloc_list < MAX_ALLOC_LIST);
407 alloc_list[i].ptr = buf;
408 alloc_list[i].size = 0;
409 alloc_list[i].file = file;
410 alloc_list[i].func = function;
411 alloc_list[i].line = line;
412 alloc_list[i].type = 9;
413 debug |= 512; /* Memory Error detect */
417 buf2 = ((char *) buf) + alloc_list[i].size;
419 if (*(long *) (buf2) != alloc_list[i].csum) {
420 alloc_list[i].type = 1;
421 debug |= 512; /* Memory Error detect */
423 buf = realloc(buffer, size + sizeof (long));
425 check = 0xa5a5 + size;
426 *(long *) ((char *) buf + size) = check;
427 alloc_list[i].csum = check;
430 printf("realloc [%3d:%3d] %p, %4ld %s %d %s -> %p %4ld %s %d %s\n",
431 i, number_alloc_list, alloc_list[i].ptr,
432 alloc_list[i].size, alloc_list[i].file, alloc_list[i].line, alloc_list[i].func,
433 buf, size, file, line, function);
435 alloc_list[i].ptr = buf;
436 alloc_list[i].size = size;
437 alloc_list[i].file = file;
438 alloc_list[i].line = line;
439 alloc_list[i].func = function;