asbury@nprdc.navy.mil (Mike Asbury) (12/29/90)
HELP! I have a large program (over 100,000 lines of code) written in Turbo C with memory leakage somewhere. I am looking for any programs that will help me find C memory allocation errors. Any pointers to shareware or commercial programs will be appreciated. Thanks in advance, Mike
gordon@osiris.cso.uiuc.edu (John Gordon) (12/30/90)
Well, here is a product that looks like its just what you need: Bounds-Checker by Nu-Mega Technologies, Inc. The ad says that it helps in solving "pointer problems and other out- of-bounds memory accesses". You can find a copy of the ad in pretty much any issue of Dr. Dobb's magazine. (Look for an ad with a picture of a penguin.) Bounds-Checker Nu-Mega Technologies, Inc P.O. Box 7780 Nashua, NH 03060-7780 (603) 888-2386 FAX (603) 888-2465 I'm not endorsing or recommending this product, I'm just answering the question. --- John Gordon Internet: gordon@osiris.cso.uiuc.edu #include <disclaimer.h> gordon@cerl.cecer.army.mil #include <clever_saying.h>
tada@athena.mit.edu (Michael J Zehr) (12/31/90)
Someone wrote:
> [help -- memory leak!!]
What I do is use allocation/deallocation macros something like:
#define _new(type) (type *)malloc_debug(sizeof(type), __FILE__, __LINE__)
and a similar one for free. then in malloc_debug and free_debug i have
code that writes the pointer being allocated/freed with the file name
and line number to a log file. (making sure the pointer is at the same
position in each line.)
because the pointers are at the same position you can do a sort on the
log file and collect all the lines regarding a particular memory
location together... (it should be a stable sort so if the same location
is returned more than once by malloc you can still sort out the file.)
then it should be pretty clear which mallocs have no associated frees.
the set of #defines above are #ifdef-ed to something like DEBUG so you
can compile without the extra overhead once you're sure there aren't any
memory leaks.
(i've used this to find memory leaks in 20,000 line programs in 5
minutes. *much* easier than poring over code or something like that.)
-michael j zehr
software engineer
consultants for management decisions, inc.
bryan@stiatl.UUCP (Bryan Donaldson) (01/04/91)
gordon@osiris.cso.uiuc.edu (John Gordon) writes: > Well, here is a product that looks like its just what you need: > Bounds-Checker by Nu-Mega Technologies, Inc. > The ad says that it helps in solving "pointer problems and other out- >of-bounds memory accesses". Unfortunately, Bounds-Checker does not check dynamically allocated memory space. We got the program to check our software, but as 60 to 90 % of the memory used in dynamically allocated, it wasn't very useful. BGD
rwskubowius@spurge.uwaterloo.ca (Rog Skubowius) (01/18/91)
In article <11589@arctic.nprdc.navy.mil> asbury@nprdc.navy.mil (Mike Asbury) writes: >HELP! I have a large program (over 100,000 lines of code) written in Turbo C >with memory leakage somewhere. I am looking for any programs that will help me >find C memory allocation errors. Any pointers to shareware or commercial >programs will be appreciated. > Thanks in advance, > Mike My first question to you is whether or not you have any function calls 'farmalloc(), farfree(), or farrealloc()'? Also, what version of the compiler are you using? If it is Turbo C++ v.1.0, the problem may not be yours. I found a bug in their farrealloc() call when I was asking for about 650K of total memory. The screen memory is overwritten by Turbo as it thinks this is valid 'usable' memory. Anyway, back to your problem. I encourage you to write 3 ( or possibly 6 ) routines, 1 per C dynamic function routine. For instance, CheckMalloc(), CheckFree(), CheckRealloc(). If you use a prefixing ( & possibly postfixing ) signature on the allocated buffer, & embed the buffer size as well, you can easily fix this problem & find the bug. Let me show this: unsigned short CheckMalloc( void ** buffer, unsigned short size ) { The application on top of CheckMalloc() wants 'size' bytes, but instead, now call malloc() for 'size' + say 3. Then, write the letters 'foo' in the first 3 bytes of the allocated memory & assign (*buffer) to the next byte following the 'foo' signature. fooXXXXXXXXX -> where a pointer to the 1st X is returned -> through (*buffer) to the calling function. } void CheckFree( void * buffer ) { Now, if the application has corrupted the buffer, you can determine it here. You see, *(buffer - 3) == 'f', *(buffer - 2) == 'o', *(buffer - 1) == 'o'. You should really macro the checking signature, its length and then use strncpy() to do the checking of signature. Anyway, if this doesn't check out...bang...you've caught some memory corruption as either the original 'CheckMalloc()'d pointer was moved, or someone overwrote part of your buffer. } CheckRealloc() { Pretty obvious what to do here --> Check out the signature & act accordingly. } This whole scheme can be improved by using a signature at the start & one at the end as well, and then putting the allocated buffer size in the buffer itself so that the end of application buffer & start of end signature can be found. Dig?
paulh@cognos.UUCP (Paul Hays) (01/18/91)
In article <11589@arctic.nprdc.navy.mil> asbury@nprdc.navy.mil (Mike Asbury) writes: >HELP! I have a large program (over 100,000 lines of code) written in Turbo C >with memory leakage somewhere. I am looking for any programs that will help me >find C memory allocation errors. Any pointers to shareware or commercial >programs will be appreciated. > Thanks in advance, > Mike In article <1991Jan18.000814.15191@watdragon.waterloo.edu> rwskubowius@spurge.uwaterloo.ca (Rog Skubowius) writes: > > ... I encourage you to write 3 ( or > possibly 6 ) routines, 1 per C dynamic function routine. For > instance, CheckMalloc(), CheckFree(), CheckRealloc(). If you > use a prefixing ( & possibly postfixing ) signature on the allocated ^^^^^^^^ ^^^^^^^^^^ Always: many arena corruptors seem to scribble on the upper signature. > buffer, & embed the buffer size as well, you can easily fix this > problem & find the bug. Let me show this: > > unsigned short CheckMalloc( void ** buffer, unsigned short size ) > { > The application on top of CheckMalloc() wants 'size' bytes, > but instead, now call malloc() for 'size' + say 3. Then, write The number of additional bytes is critical in some applications; the buffer must be aligned on many mahines. > the letters 'foo' in the first 3 bytes of the allocated memory > & assign (*buffer) to the next byte following the 'foo' signature. > > fooXXXXXXXXX -> where a pointer to the 1st X is returned > -> through (*buffer) to the calling function. > > } > > void CheckFree( void * buffer ) > { > Now, if the application has corrupted the buffer, you can > determine it here. You see, *(buffer - 3) == 'f', > *(buffer - 2) == 'o', *(buffer - 1) == 'o'. You should really > macro the checking signature, its length and then use > strncpy() to do the checking of signature. Anyway, if this > doesn't check out...bang...you've caught some memory corruption > as either the original 'CheckMalloc()'d pointer was moved, or > someone overwrote part of your buffer. > } [etc.] We use a shell around the malloc() routine as well; mine is specified to match the C library routine with additional side effects: - The allocator returns a 'char *' (hey, it's pre-ANSI). - The signature below the returned address is large enough to ensure that the address is suitably aligned for an object of any type. (This 8 bytes for the RISC machines.) - The allocator saves information used for automatic checking. This code is only linked into development versions of the programs because of the overhead (see below). For the release version, the C preprocessor is used to substitute the actual C library routines: #define mallocph(s) malloc(s) /* use C library allocator */ These routines get very serious about detecting corruption of the arena. The module that defines the checking routines also defines a large static array of structs used to track the status of each block allocated. Each block gets a serial number that is recorded in its struct, along with the block's size and address. (The checking routines keep only 'signature' bytes in the allocated space; everything else is in the array. After all, we're looking for arena corrupters ...) Whenever any block is allocated, reallocated, or freed, an internal routine scans the static array and checks all of the signatures at the bottom and top of each block. It seems that many corruptors call the routines strcat(), strncpy(), memset(), memcpy(), and the like to scribble on the arena for them. The latest incarnation of the checker includes shells for these routines as well; the shell routines call the C library routine and then test to see whether it misbehaved. Amazingly, the overhead for all of this checking has not proven to be a problem even in programs which use the arena excessively. -- Paul Hays Cognos Incorporated S-mail: P.O. Box 9707 Voice: (613) 738-1338 ext 3804 3755 Riverside Drive FAX: (613) 738-0002 Ottawa, Ontario uucp: uunet!mitel!cunews!cognos!paulh CANADA K1G 3Z4