You can ask malloc to check the consistency of dynamic memory by
using the mcheck function and preloading the malloc debug library
libc_malloc_debug using the LD_PRELOAD environment variable.
This function is a GNU extension, declared in mcheck.h.
int mcheck (void (*abortfn) (enum mcheck_status status)) ¶Preliminary: | MT-Unsafe race:mcheck const:malloc_hooks | AS-Unsafe corrupt | AC-Unsafe corrupt | See POSIX Safety Concepts.
Calling mcheck tells malloc to perform occasional
consistency checks. These will catch things such as writing
past the end of a block that was allocated with malloc.
The abortfn argument is the function to call when an inconsistency
is found. If you supply a null pointer, then mcheck uses a
default function which prints a message and calls abort
(see Aborting a Program). The function you supply is called with
one argument, which says what sort of inconsistency was detected; its
type is described below.
It is too late to begin allocation checking once you have allocated
anything with malloc. So mcheck does nothing in that
case. The function returns -1 if you call it too late, and
0 otherwise (when it is successful).
The easiest way to arrange to call mcheck early enough is to use
the option ‘-lmcheck’ when you link your program; then you don’t
need to modify your program source at all. Alternatively you might use
a debugger to insert a call to mcheck whenever the program is
started, for example these gdb commands will automatically call mcheck
whenever the program starts:
(gdb) break main Breakpoint 1, main (argc=2, argv=0xbffff964) at whatever.c:10 (gdb) command 1 Type commands for when breakpoint 1 is hit, one per line. End with a line saying just "end". >call mcheck(0) >continue >end (gdb) ...
This will however only work if no initialization function of any object
involved calls any of the malloc functions since mcheck
must be called before the first such function.
enum mcheck_status mprobe (void *pointer) ¶Preliminary: | MT-Unsafe race:mcheck const:malloc_hooks | AS-Unsafe corrupt | AC-Unsafe corrupt | See POSIX Safety Concepts.
The mprobe function lets you explicitly check for inconsistencies
in a particular allocated block. You must have already called
mcheck at the beginning of the program, to do its occasional
checks; calling mprobe requests an additional consistency check
to be done at the time of the call.
The argument pointer must be a pointer returned by malloc
or realloc. mprobe returns a value that says what
inconsistency, if any, was found. The values are described below.
This enumerated type describes what kind of inconsistency was detected in an allocated block, if any. Here are the possible values:
MCHECK_DISABLEDmcheck was not called before the first allocation.
No consistency checking can be done.
MCHECK_OKNo inconsistency detected.
MCHECK_HEADThe data immediately before the block was modified. This commonly happens when an array index or pointer is decremented too far.
MCHECK_TAILThe data immediately after the block was modified. This commonly happens when an array index or pointer is incremented too far.
MCHECK_FREEThe block was already freed.
Another possibility to check for and guard against bugs in the use of
malloc, realloc and free is to set the environment
variable MALLOC_CHECK_. When MALLOC_CHECK_ is set to a
non-zero value less than 4, a special (less efficient) implementation is
used which is designed to be tolerant against simple errors, such as
double calls of free with the same argument, or overruns of a
single byte (off-by-one bugs). Not all such errors can be protected
against, however, and memory leaks can result. Like in the case of
mcheck, one would need to preload the libc_malloc_debug
library to enable MALLOC_CHECK_ functionality. Without this
preloaded library, setting MALLOC_CHECK_ will have no effect.
Any detected heap corruption results in immediate termination of the process.
There is one problem with MALLOC_CHECK_: in SUID or SGID binaries
it could possibly be exploited since diverging from the normal programs
behavior it now writes something to the standard error descriptor.
Therefore the use of MALLOC_CHECK_ is disabled by default for
SUID and SGID binaries.
So, what’s the difference between using MALLOC_CHECK_ and linking
with ‘-lmcheck’? MALLOC_CHECK_ is orthogonal with respect to
‘-lmcheck’. ‘-lmcheck’ has been added for backward
compatibility. Both MALLOC_CHECK_ and ‘-lmcheck’ should
uncover the same bugs - but using MALLOC_CHECK_ you don’t need to
recompile your application.