
[NOTE:  Also look at /oskit/doc/libmemdebug.tex, that's probably
more likely to be updated...]

This implements a fence-post style malloc debug library.  Over- and
under- runs can be detected.  Mismatches between malloc() style and
smalloc() style allocations and frees are detected.  Memory is
cleared on allocation and when it is freed, to force errors on
memory used after it is freed.  sfree() size is checked against that
used when the block is created.  Double frees are detected.

All of the standard functions are covered: malloc, memalign, calloc,
realloc, free, and smalloc, smemalign, and sfree.

Whenever a problem is encountered a backtrace (in the form of eip
values) is dumped (backtracing from the _allocation_ of the memory).
File and line number information for where the allocation call was
made are also printed (if available.)  If the failure was detected in
a call to free, the file and line of that call are printed. 

When correctable errors are detected (eg, sfree'ing a malloc'd block,
or sfree'ing with the wrong size block.) the correct thing will be
done, and the program will continue as normal (except for the malloc
bogosity dump.)

There are a few auxiliary functions useful for detecting errors.
First is memdebug_ptrchk() which takes a pointer and runs a set
of sanity checks on it and the fence posts.  _mark() and 
_check() are useful for narrowing down leaks.  Place a _mark() 
and an _check at points in the code where no new allocations
after the _mark() should be around at the point of the _check().
memdebug_sweep() runs a sanity check on all currently allocated
memory blocks.

[Note that file and line number information is only available if
you're using the macro wrappers for the allocaters defined in
malloc_debug.h.]

There is one configure option in the debug_malloc header file--it 
controls whether running out of memory is instantly fatal, or if
null should be returned.

To use the library, just include -lmemdebug on the linker command line
before the standard C library (or wherever it is you're getting
malloc, etc.)

			-----

Every malloc is buffered on either end by a "fence post" of debugging
information.

			-----

There are _several_ layers in the debugging version of the malloc
functions.

For example:

malloc() --> __traced_malloc() --> memdebug_malloc()

The first two will vary for which function (realloc, calloc, 
smemalign, etc), but the last is constant for the whole
debug library.

The malloc_debug.h macros use the __traced_malloc() entry points
directly (suppling valid file and line information in the process).

[In this case each entry point (smemalign, realloc, etc.) has its own
implementation.] 

Note that the default malloc() and memdebug_malloc() CAN HAVE
DIFFERENT POLICIES. memdebug_malloc() uses the lmm library directly,
in the same way as the default malloc.  But, malloc can be 
overridden, and memdebug_malloc will not change. (This can be
a good thing, as long as you know about it.)

			-----

All of the routines use an overridable memdebug_printf() to do output,
you should override this if you cannot guarantee that vfprintf() calls 
will not allocate memory.  Belive me, it'll make your life easier.

The allocation routines also all call mem_lock() and mem_unlock() to 
protect access to the global malloc_lmm.

