Message-ID: <386E2A6E.9282965F@teleline.es> Date: Sat, 01 Jan 2000 17:25:18 +0100 From: Mariano Alvarez =?iso-8859-1?Q?Fern=E1ndez?= X-Mailer: Mozilla 4.5 [es] (Win95; I) X-Accept-Language: es MIME-Version: 1.0 To: djgpp-workers AT delorie DOT com Subject: Mini malloc debugger Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Reply-To: djgpp-workers AT delorie DOT com Here, there are my patch to add the mini-malloc debugger to the stock malloc routine for DJGPP, I have used the malloc.c in the last 2.03 alpha lib to make the diff. It's the same utility I mailed for fmalloc.c to the djgpp list, and Eli pointed to me to do the same for the stock malloc.c. The overhead is so little (I think) that using constructions like "if( mini_malloc_debugger ) do things" are unnecessary, the only question is if any-body disagree whith that. I really think is very useful. Here are the diff: *** src/libc/ansi/stdlib/malloc.old Fri Aug 20 18:46:58 1999 --- src/libc/ansi/stdlib/malloc.c Tue Dec 28 23:44:28 1999 *************** *** 6,11 **** --- 6,17 ---- #include #include + long malloc_info_memory = 0; + long malloc_info_nomem = 0; + long malloc_info_nmalloc = 0; + long malloc_info_nfree = 0; + long malloc_info_nfree0 = 0; + typedef struct BLOCK { size_t size; struct BLOCK *next; *************** *** 97,103 **** return rv; } ! #define RET(rv) CHECK(rv); ENDSZ(rv) |= 1; rv->size |= 1; return DATA(rv) void * malloc(size_t size) --- 103,110 ---- return rv; } ! #define RETD(rv) malloc_info_memory += (rv->size & ~1) + 16; return DATA( rv ) ! #define RET(rv) CHECK(rv); ENDSZ(rv) |= 1; rv->size |= 1; RETD(rv) void * malloc(size_t size) *************** *** 106,111 **** --- 113,119 ---- BLOCK *rv, **prev; static BLOCK *expected_sbrk = 0; + malloc_info_nmalloc++; if (sizenext; ! return DATA(rv); } } #endif --- 127,133 ---- if (rv) { smallblocks[size/ALIGN] = rv->next; ! RETD(rv); } } #endif *************** *** 194,200 **** --- 202,211 ---- chunk_size = size+16; /* two ends plus two placeholders */ rv = (BLOCK *)sbrk(chunk_size); if (rv == (BLOCK *)(-1)) + { + malloc_info_nomem++; return 0; + } #if DEBUG printf("sbrk(%d) -> %08x, expected %08x\n", chunk_size, rv, expected_sbrk); #endif *************** *** 281,289 **** --- 292,306 ---- { int b; BLOCK *block; + + malloc_info_nfree++; if (ptr == 0) + { + malloc_info_nfree0++; return; + } block = (BLOCK *)((char *)ptr-4); + malloc_info_memory -= (block->size & ~1) + 16; #if NUMSMALL if (block->size < SMALL) And here, there are the documentation, I don't know where to put it, and it will be nice if somebody check my horrible english. ----------------------------------- The DJGPP mini-malloc debugger. This mini-malloc debugger is intended for use during program development, using a little group of global variables. They are: malloc_info_memory store the real heap memory used at any time. malloc_info_nomem times malloc return whith no memory. malloc_info_nmalloc times malloc was called. malloc_info_nfree times free was called. malloc_info_nfree0 times free was called whith a NULL pointer. How to use. First you must to declare the variables in the routine you use to show the data: extern long malloc_info_memory; extern long malloc_info_nomem; extern long malloc_info_nmalloc; extern long malloc_info_nfree; extern long malloc_info_nfree0; The prefered method is to check the malloc_info values before and after run a new feature in your program, you must find that the next expresions: 1) malloc_info_memory 2) malloc_info_nmalloc - malloc_info_nfree - malloc_info_nomem are equals before and after, and the malloc_info_nfree0 is always 0. If not you have a memory hole. You must note that some libc routines can get some memory from the heap and don't free it, so if you find there are a little difference in the second expresion, check again whithout ending the program. Here there are a simple routine to do the test, you can call it whith show_malloc_info( stdout ) or show_malloc_info( stderr ). void show_malloc_info( FILE *f ) { extern long malloc_info_memory; extern long malloc_info_nomem; extern long malloc_info_nmalloc; extern long malloc_info_nfree; extern long malloc_info_nfree0; fprintf( f,"Mem:%ld Dif:%ld\n", malloc_info_memory, malloc_info_nmalloc - malloc_info_nfree - malloc_info_nomem ); if( malloc_info_nfree0 ) > 0 ) fprintf( f,"%ld NULL pointers dereferences!\n", malloc_info_nfree0 ); } If you are using a GUI or a TUI it will be better to write your own routine and asociate it to a hot key, showing the values in a window. Grettings. M.Alvarez