MalCheck

Check dynamic allocations in C


Library icon

Download MalCheck v1.1.1.1 [21k Zip file]

Download MalCheck Source (v2.0) [683k Zip file]


What it does

This library gives you some help to track down program errors involving dynamically allocated memory blocks. (That is, blocks manipulated with malloc(), realloc(), calloc() and free())

These usually manifest themselves as unpredictable crashes at locations in the program that look perfectly correct. The damage was done at an earlier point, but only shows itself later.

A surefire pointer to such a problem is when the postmortem backtrace indicates that the last routine called was one of the above four functins.

This package keeps an eye on dynamically allocated blocks and tries to see if data was written outside the block or into free or dealloc blocks. (Free blocks are blocks released by free(), dealloc blocks are blocks left behind when realloc() needed to move data to a bigger block.)

How to use MalCheck

Include this line in the sources you want to check:

#include "MalCheck:malcheck.h"

Add the library 'MalCheck:o.malcheck' to the list given to the Link command in your Makefile. Note: If you use the (obsolete) ansilib, then put the malcheck library before C:o.ansilib.

Define the macro 'MALCHECK' by passing -DMALCHECK to the compile commands. Note: you can switch off MalCheck without changing the sources by compiling without this macro defined.

Make sure that the MalCheck$Path is set (e.g. by calling SetVars, which can be found in the package).

Make your software. When you run it, checks will be performed and output written to stderr.

How it works

MalCheck intercepts calls to malloc(), calloc(), realloc() and free(), by replacing them with macros that call special library functions. These functions then perform the normal action requested, with a little extra. When blocks are allocated, a header with maintenance information is put before them, and a 'magic number' (m3) is put after the block. The header is used to maintain a list of blocks and to keep information about each block. Changes in the data can be detected by a calculated CRC which is kept in the header. The header itself is protected by it's own CRC, plus magic numbers at the start (m1) and at the end (m2).

Every time one of the above functions is called by the user program, the library runs though it's list of blocks and looks for suspicious things. For example: a change in m3 will show that probably the end of the allocated block was overwritten. This commenly happens when a string written to a block is too large for that block (maybe the terminating zero was forgotten in the count). Problems are reported on stderr, if their level is equal to or worse than the current report level.

If nothing desastrous has happened, the MalCheck function then performs the duty it was called for, checking whether nothing illegal is done (like calling free() with a pointer that does not point to an existing block). When no problems occured equal to or worse than the current quit level, the routine returns to the user program.

As an extra, atexit() is used to install a routine which produces a listing of all blocks when the program exits.

Manipulating output

MalCheck includes the following routines
MalCheck_setlevel(level);
Set the level of output, rangeing from fatal messages only up to giving a list of all blocks on each call.
MalCheck_setquit(level);
Set the level of error at which MalCheck will exit.
MalCheck_setoutput(File *);
Direct the output stream to a given file.

More information

For further details you can see the ReadMe file here. You can also check out the Frequently Asked Questions.

Release notes for version 1.1.1.1


Release notes for version 2.0


[home]
File identification:
$Id: malcheck.html 1.5 2022-07-09 21:42:06+02 erikgrnh Exp $