   This file is an introduction to the Malloc library which handles
general memory heap management.

   Copyright (C) 1992 by Gray Watson and the Antaire Corporation.

   Permission is granted to make and distribute verbatim copies of this
manual provided the copyright notice and this permission notice are
preserved on all copies.

   Permission is granted to copy and distribute modified versions of
this manual under the conditions for verbatim copying, provided also
that the section entitled "Copying" are included exactly as in the
original, and provided that the entire resulting derived work is
distributed under the terms of a permission notice identical to this
one.

   Permission is granted to copy and distribute translations of this
manual into another language, under the above conditions for modified
versions, except that the section entitled "Copying" may be included in
a translation approved by the author instead of in the original English.

Malloc Debug Library
********************

   This file documents the general-usage and the inner-workings of the
memory allocation or "malloc" library it accompanies.

   This malloc library has been designed as a drop in replacement for
the system's malloc, realloc, calloc, free and other memory management
routines.  For more information about their capabilities, do a `man 3
malloc' to read the system's manual pages.

   What is unique about this library is that it contains a number of
powerful debugging facilities including very comprehensive heap testing
and excellent run-time debugging information.  We have found these
capabilities to be superb development tools.

   I can be reached at `<gray.watson@antaire.com>' with any questions
or general comments.

   Gray Watson, Antaire Corporation.

Library Copying Conditions.
***************************

   This package is covered by the GNU Library Public License.  See the
file `COPYING-LIB' for details.  If you would like to do something with
this package that you feel is reasonable but prohibited by the license,
please contact me to see if we can work it out.

   *NOTICE*: this is not the GNU Public License but the *library*
public license.  This license allows you to do more with the library
than the standard public license distributed with most GNU software.
Please read `COPYING-LIB' or contact me for more information.

   The rest of this section contains some messages from the Free
Software Foundation.  If you find this stuff offensive or annoying,
remember that you probably did not spend any money to get this library
so feel free to heave it into the bit bucket.

   The licenses for most software are designed to take away your
freedom to share and change it.  By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.

   This license, the Library General Public License, applies to some
specially designated Free Software Foundation software, and to any other
libraries whose authors decide to use it.  You can use it for your
libraries, too.

   When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it in
new free programs; and that you know you can do these things.

   To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the library, or if you modify it.

   For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link a program with the library, you must provide complete
object files to the recipients so that they can relink them with the
library, after making changes to the library and recompiling it.  And
you must show them these terms so they know their rights.

   Our method of protecting your rights has two steps: (1) copyright the
library, and (2) offer you this license which gives you legal permission
to copy, distribute and/or modify the library.

   Also, for each distributor's protection, we want to make certain that
everyone understands that there is no warranty for this free library.
If the library is modified by someone else and passed on, we want its
recipients to know that what they have is not the original version, so
that any problems introduced by others will not reflect on the original
authors' reputations.

Basic Description of Terms and Functions.
*****************************************

   This section provides a basic definition of terms used throughout the
manual as well as a brief overview of the basic malloc functions and
examples of their use.  It is quite unnecessary for you to read this
section if you are familiar with using the heap allocation functions.

For Defining General Terms and Concepts.
========================================

   Any program can be divided into 2 logical parts: text and data.
Text is the actual program code in machine-readable format and data is
the information that the text operates on when it is executing.  The
data, in turn, can be divided into 3 logical parts according to where
it is stored: "static", "stack", and "heap".

   Static data is the information whose storage space is compiled into
the program.
             /* global variables are allocated as static data */
             int numbers[10];

             main()
             {
                ...
             }
   Stack data is data allocated at run-time to hold information used
inside of functions.  This data is managed by the system in the space
called stack space.

             void foo()
             {
                /* this local variable is allocated on the stack */
                float total;

                ...
             }
   Heap data is also allocated at run-time and provides a programmer
with dynamic memory capabilities.

             main()
             {
                char * string;
                ...

                /* allocate a string of 10 bytes */
                string = (char *)malloc(10);
                ...
                /* de-allocate the string now that I'm done with it */
                (void)free(string);

                ...
             }
   It is the heap data that is managed by this library.

   Although the above is an example of how to use the malloc and free
commands, it is not a good example of why using the heap for run-time
storage is useful.

   Consider this: You write a program that reads a file into memory,
processes it, and displays results.  You would like to handle files with
arbitrary size (from 10 bytes to 1.2 megabytes and more).  One problem,
however, is that the entire file must be in memory at one time to do the
calculations.  You don't want to have to allocate 1.2 megabytes when you
might only be reading in a 10 byte file because it is wasteful of system
resources.  Also, you are worried that your program might have to handle
files of more than 1.2 megabytes.

   A solution: first checkout the file's size and then, using the
heap-allocation routines, get enough storage to read the entire file
into memory.  The program will only be using the system resources
necessary for the job and you will be guaranteed that your program can
handle any sized file.

Functionality Supported by all Malloc Libraries.
================================================

   All malloc libraries support 4 basic memory allocation commands.
These include "malloc", "calloc", "realloc", and "free".

`malloc'
     Usage: `pnt = (type *)malloc(unsigned int size);'

     The malloc routine is the basic memory allocation routine.  It
     allocates an area of size bytes.  It will return a pointer to the
     space requested.

`calloc'
     Usage: `pnt = (type *)calloc(unsigned int number, unsigned int
     size);'

     The calloc routine allocates a certain number of items, each of
     size bytes, and returns a pointer to the space.  It is appropriate
     to pass in a `sizeof(type)' value as the size argument.

     Also, calloc nulls the space that it returns, assuring that the
     memory is all zeros.

`realloc'
     Usage: `new_pnt = (type *)realloc(void * old_pnt, unsigned int
     new_size);'

     The realloc function expands or shrinks the memory allocation in
     old_pnt to new_size number of bytes.  Realloc copies the
     information in old_pnt into the new_pnt space up to new_size bytes
     or until it copies all of the information from old_pnt.

`free'
     Usage: `(void)free(void * pnt);'

     The free routine releases an allocation returned by malloc,
     calloc, or realloc back to the heap.  This allows other parts of
     the program to re-use memory that is not needed anymore.  It also
     guarantees that the process does not grow too big and swallow a
     large portion of the system resources.

   *NOTE*: the returned address from the memory allocation/reallocation
functions should *always* be cast to the appropriate pointer type for
the variable being assigned.

   *WARNING*: there is a quite common myth that all of the space that
is returned by malloc libraries has already been cleared.  *Only* the
calloc routine will zero the memory space it returns.

Description of the Benefits of the Library.
*******************************************

General Debugging Concepts.
===========================

   The features of this library are controlled by a number of
environmental variables.  They enable the memory debugging features at
runtime to help locate problems, chart memory leaks, provide basic
bounds checking, log statistics, etc.. See Environment variables.

   The debugging features that are available can be broken down into a
couple basic classifications:

`file and line number information'
     One of the nice things about a good debugger is its ability to
     provide the file and line number of an offending piece of code.
     This library attempts to give this functionality with the help of
     "cpp", the C preprocessor.  If the file `malloc.h' is included,
     the library can provide file and line information for the warning
     messages and errors it generates.

`fence-post (i.e. bounds) checking'
     "Fence-post" memory is the area immediately above or below memory
     allocations.  I have found it all to easy to write code that
     accesses above or below an allocation (especially when dealing
     with arrays or strings).  The library can write special values in
     the areas around every allocation so it will notice when these
     areas have been overwritten.

     *NOTE*: The library cannot notice when the program reads from these
     areas, only when it writes values.  Also, fence-post checking will
     increase the amount of memory the program allocates.

`heap-constancy verification'
     The administration of the library is reasonably complex.  If any
     of the heap-maintenance information is corrupted, the program will
     either crash or give unpredictable results.

     By enabling heap-consistency checking, the library will run
     through its administrative structures to make sure all is in
     order.  This will mean that problems will be caught faster and
     diagnosed better.

     The drawback of this is, of course, that the library often takes
     quite a long time to do this.  It is suitable to enable this only
     during development and debugging sessions.

     *NOTE*: the heap checking routines cannot guarantee that the tests
     will not cause a segmentation-fault if the heap administration
     structures are properly (or improperly if you will) overwritten.
     In other words, they will verify that everything is okay but may
     not inform the user of problems in a graceful manner.

`logging statistics'
     One of the initial reasons why I personally wanted malloc-debug
     capabilities is to track my programs' memory usage; specifically to
     locate memory "leaks" which are places where allocated memory is
     never getting freed.

     The library has a number of logging capabilities that can track
     run-time memory usage, administrative actions, final program
     statistics, as well as un-freed memory pointers.  This information
     is also good at providing more general debugging feedback.

`examining unfreed memory'
     Another common problem with programs is that they free a memory
     pointer but then use go on to use it again by mistake.  This can
     lead to mysterious crashes and unexplained problems.

     To combat this, the library can write special values into a block
     of memory after it has been freed.  This serves two purposes: it
     will make sure that the program will get garbage data if it trying
     to access the area again, and it will allow the library to verify
     the area later for signs of overwriting.

   If any of the above debugging features detect an error, the library
will try to recover.  If logging is enabled then an error will be
logged with as much information as possible.

   The error messages that the library displays are designed to give the
most information for developers.  If the error message is not
understood, then it is most likely just trying to indicate that a part
of the heap has been corrupted.  The bug is most likely near the last
call made to the library so reviewing the code around this area is
recommended.

   The library can be configured to quit immediately when an error is
detected and to dump a core file or memory-image.  This can be examined
with a debugger to determine the source of the problem.

   When running our programs in a debugger such as gdb (the *excellent*
GNU debugger), I always put a break-point in `_malloc_perror()' which
is the internal error routine for the library.  The program will then
hit the break-point as soon as a memory problem is detected.

   Other malloc-debug libraries also support the ability to dump core
and then continue running.  I decided not to support this once it was
determined that some versions of `fork' make calls to malloc which
would cause the library to go recursive.

   *NOTE*: do not be surprised if the library catches problems with
your system's library routines.  It took me four hours once to finally
come to the conclusion that the localtime call, included in SunOS
release 4.1, was overwriting one of its fence-post markers.

Environment Variables - Their Names and Features.
=================================================

   "Environment variables" are variables that are part of the user's
working environment and are shared by all the programs.  The below
variables are used by the malloc library to enable or disable the memory
debugging features, at runtime.

   They can be set either by hand or with the help of the malloc_dbg
program.  See malloc_dbg program.

   To set them by hand, C shell (or tcsh) users need to invoke:

             setenv variable value;
   Bourne shell (or bash, ksh) users should use:

             variable=value;
             export variable;

`MALLOC_DEBUG'
     This env variable should be set to a value in hexadecimal which
     corresponds to a set of functionality tokens.  See Debug tokens.
     For instance, if the user wanted to enabled logging of
     memory transactions (value `0x008') and wanted to check fence-post
     memory (value `0x400') then `MALLOC_DEBUG' should be set to
     `0x408'.

     Don't worry about remembering all the hex values of the tokens, the
     malloc_dbg program automates the setting of this variable
     especially.

`MALLOC_LOGFILE'
     Set this variable to a filename so that if `MALLOC_DEBUG' has
     logging enabled, the library can log transactions, administration
     information, and/or errors to the file so memory problems and
     usage can be tracked.

`MALLOC_ADDRESS'
     When this env variable is set to a hex address (taken from the
     malloc log-file for instance) malloc will abort when it finds
     itself either allocating or freeing that address.

     The address can also have an `:number' argument.  For instance, if
     it was set it to `0x3e45:10', the library will kill itself the 10th
     time it sees address `0x3e45'.

     This makes it easier to track down specific addresses not being
     freed.

`MALLOC_INTERVAL'
     By setting this env variable to a number X, malloc will only check
     the heap every X times.  This means a number of `MALLOC_DEBUG'
     features can be enabled while still running the program within a
     finite amount of time.

     I have found that a setting of `100' works well with reasonably
     memory intensive programs.  This of course means that the library
     will not catch errors exactly when they happen but possibly 100
     library calls later.

`MALLOC_START'
     Set this env variable to a number X and malloc will begin checking
     the heap after X times.  This means the intensive debugging can be
     started after a certain point in a program.

     `MALLOC_START' also has the format file:line.  For instance, if it
     is set to `malloc_t.c:126' malloc will start checking the heap
     after it sees a malloc call from the `malloc_t.c' file, line number
     126.  If line number is 0 then malloc will start checking the heap
     after it sees a call from anywhere in the `malloc_t.c' file.

     This allows the intensive debugging to be started after a certain
     routine or file has been reached in the program.

Env Variable Setting Utility.
=============================

   The malloc_dbg program is designed to assist in the setting of the
environmental variables, especially `MALLOC_DEBUG'. See Environment variables.
It is designed to print the shell commands necessary to
make the appropriate changes to the environment. Unfortunately, it
cannot make the changes on its own so the output from malloc_dbg should
be sent through the `eval' shell command which will do the commands.

   With shells that have aliasing or macro capabilities: csh, tcsh,
bash, ksh, etc., setting up an alias to malloc_dbg to do the eval call
is recommended.  csh/tcsh users (for example) should put the following
in their `.cshrc' file:

             alias malloc 'eval `malloc_dbg \!*`'
   This allows the user to execute `malloc args'.

   The most basic usage for the program is `malloc_dbg [-b] tag'.  The
-b flag is for generating Bourne-shell type commands (C-shell type are
the default).  The tag argument should match a line from the user's
run-time configuration file.  See RC file.

   Here is a detailed list of the flags that can passed to malloc_dbg:

`-a address'
     Set the `MALLOC_ADDRESS' variable with the string address (or
     alternatively address:number).

`-b'
     Output Bourne-shell type commands.  (C-shell type output is the
     default).

`-c'
     Clear/unset all of the variables not specified with other
     arguments.

     *NOTE*: clear will never unset the `MALLOC_DEBUG' variable. Use
     `-d 0' or a tag to `none' to achieve this.

`-d bitmask'
     Set the MALLOC_DEBUG to the bitmask value which should be in hex.
     This is overridden (and unnecessary) if a tag is specified.

`-e errno'
     Print the malloc error string that corresponds to errno.

`-f filename'
     Use this configuration file instead of the RC file
     `$HOME/.mallocrc'.

`-i number'
     Set the `MALLOC_INTERVAL' env variable to number.

`-l filename'
     Set the `MALLOC_LOGFILE' env variable to filename.

`-s number'
     Set the `MALLOC_START' env variable to number (alternatively
     file:line).

   If no arguments are specified, malloc_dbg dumps out the current
settings that you have for the malloc environmental variables.  For
example:

             MALLOC_DEBUG == '0x6417' (debug1)
             MALLOC_ADDRESS == '0'
             MALLOC_INTERVAL not set
             MALLOC_LOGFILE == 'malloc'
             MALLOC_START not set

Format of the Run-Time Configuration File.
==========================================

   The name of default "RC file" (or run-time configuration file) is
`$HOME/.mallocrc'.  The `$HOME' environmental variable should be set by
the system to point to your home-directory.

   The rc file file should contain lines in the general form of:

   `tag token1, token2, ...'

   tag is to be matched with the tag argument passed to the malloc_dbg
program, token1, token2, ... are debug capability tokens. See
malloc_dbg program and Debug tokens.

   A line can be finished with a '\' meaning it continues onto the next
line.  Lines beginning with '#' are treated as comments and are ignored
along with empty lines.

   I have the below contents in my `.mallocrc' file:

     #
     # Malloc run-time configuration file for our malloc-debug library
     #

     # no debugging
     none    none

     # basic debugging
     debug1	log-stats, log-non-free, log-perror, log-bad-pnt, check-fence

     # more logging and some heap checking
     debug2	log-stats, log-non-free, log-perror, log-trans, log-bad-pnt, \
     	check-fence, check-heap, check-lists, error-abort

     # good utilities
     debug3	log-stats, log-non-free, log-perror, log-trans, log-bad-pnt, \
     	log-admin, check-fence, check-heap, check-lists, realloc-copy, \
     	free-blank, error-abort

     ...
   With the above file, when I say `eval `malloc_dbg debug1`', I enable
the logging of statistics, the logging of non-freed memory, logging of
errors, logging of bad pointer information, and the checking of
fence-post memory areas.

   When I say `eval `malloc_dbg none`', all memory debugging features
are disabled.

Description of the Debugging Token Flags.
=========================================

   The below tokens and their corresponding descriptions are for the
setting of the `MALLOC_DEBUG' environmental variable Environment variables.
They should be specified in the user's `.mallocrc' file
RC file.

`none'
     no debugging functionality

`log-stats'
     log general statistics when malloc_shutdown is called

`log-non-free'
     log non-freed memory pointers when malloc_shutdown is called

`log-perror'
     log internal error-messages

`log-trans'
     log general memory transactions

`log-bad-pnt'
     log information about bad-pointers

`log-admin'
     log full administrative information

`log-blocks'
     log detailed block information when malloc_heap_map is called

`log-unknown'
     like log-non-free but logs unknown non-freed memory pointers

`check-fence'
     check fence-post memory areas

`check-heap'
     verify heap administrative structure

`check-lists'
     examine internal heap linked-lists

`check-dblock'
     do detailed checking on small allocations

`check-dblock-fence'
     check the fence-post areas of small allocations

`check-free'
     check to see if free space has been overwritten

`check-funcs'
     check the arguments of some functions (mostly string operations)
     looking for bad pointers

`realloc-copy'
     always copy data to a new pointer when realloc

`free-blank'
     write special values (non-0) into space when it is freed

`error-abort'
     abort the program (and dump core) on errors

`alloc-blank'
     write special values (non-0) into space when it is alloced

`heap-check-map'
     log a heap-map to the logfile every time the heap is checked

`print-perror'
     log any errors and messages to the screen via standard-error

Check Certain Function Arguments.
=================================

   One potential problem with the library and its multitude of checks
and diagnoses is that they only get performed when a malloc function is
called.  One solution this is to include `malloc.h' and compile your
source code with the `MALLOC_FUNC_CHECK' flag defined and enable the
`check-funcs' token Debug tokens.

             gcc -DMALLOC_FUNC_CHECK file.c
   Once you have compiled your source with FUNC_CHECK enabled, you will
have to recompile with it off to disconnect the library Disabling the Library.

   When this is defined malloc will override a number of functions and
will insert a routine which knowns how to check its own arguments and
then call the real function.  Malloc can check such functions as bcopy,
index, strcat, and strcasecmp (for the full list see the end of
`malloc.h').

   When you call strlen, for instance, malloc will make sure the string
argument's fence-post areas have not been overwritten, its file and line
number locations are good, etc.  With bcopy, malloc will make sure that
the destination string has enough space to store the number of bytes
specified.

   For all of the arguments checked, if the pointer is not in the heap
then it is ignored since malloc does know anything about it.

   *NOTE*: this is one of the newest parts of the library so problems
may still be lurking.

How to Run Programs With the Library.
*************************************

For Providing File/Line Debugging Information.
==============================================

   By including `malloc.h' in your C files, your calls to calloc, free,
malloc, or realloc are replaced with calls to _calloc_leap, _free_leap,
_malloc_leap, and _realloc_leap.

   These leap macros use the c-preprocessor `__FILE__' and `__LINE__'
macros which get replaced at compilation time with the current file and
line-number of the source code in question.  The leap routines take
this information and pass it on to the library making it able to
produce verbose reports on memory not freed:

     	not freed: 0x38410 ( 22 bytes) from 'malloc_t.c:92'
             not freed: 0x38600 ( 10232 bytes) from 'malloc_t.c:104'
   These lines from a log file shows that two allocations were not
freed. One at address 0x38410 of size 22 bytes in source file
`malloc_t.c' at line 92 and another at address 0x38600 of size 10232
bytes at line 104 of `malloc_t.c'.

   Along with the above leap macros, `malloc.h' also contains the
following macros which I have been using for all our memory allocation
needs for some time now.  They take care of all the type-casting and
make the code look much cleaner (IMHO).

`ALLOC(type, count)'
     Usage: `long_pnt = ALLOC(long, 30);'.  This means allocate space
     for 30 longs.

`MALLOC(size)'
     Usage: `char_pnt = MALLOC(1000);'.  This is like ALLOC but for
     characters only.  It means allocate space for 1000 characters.

`CALLOC(type, count)'
     Usage: `infp = CALLOC(struct info_st, 100);'.  This means allocate
     space for 100 info_st structures and zero them all.

     *NOTE*: the arguments for the CALLOC macro are sort of reversed
     from calloc(unsigned int count, unsigned int size).

`REALLOC(pnt, type, count)'
     Usage: `long_pnt = REALLOC(old_pnt, long, 10);'.  This takes
     old_pnt and and changes its size to accommodate 10 longs.

`REMALLOC(pnt, size)'
     Usage: `char_pnt = REMALLOC(char_pnt, 100);'.  This is like REALLOC
     but for characters only.  It takes char_pnt and changes its size
     to 100 characters.

`FREE(pnt)'
     Usage: `(void)FREE(pnt);'.  This frees memory pointers.

`STRDUP(string)'
     Usage: `char_pnt = STRDUP("hello");'.  This macro duplicates the
     functionality of the `strdup' function.  string can be either a
     static string like "hello" or a character pointer.  Non-gcc users
     should use `STRDUP("hello", char_pnt);' where char_pnt is the
     variable which will be assigned to the pointer to the copy of
     "hello".

`BDUP(pnt, size)'
     Usage: `new_item_pnt = BDUP(&item, sizeof(item));'.  This allocates
     space for size bytes, copies size bytes from pnt into the new
     allocation and returns it.  It is like strdup but for non-strings.
      Non-gcc users should use `BDUP(&item, sizeof(item),
     new_item_pnt);' where new_item_pnt is the variable which will be
     assigned the pointer to the copy of item.

   In the above macro list, I have also included a STRDUP and a BDUP
macro. STRDUP, for those who are not familiar with the strdup function,
takes a string, allocates enough information to store the string (along
with its null character), and then copies the string into the new
space.  This macro does not actually call strdup but provides the same
functionality and provides file and line memory information to the
library.

   BDUP is a function that I invented.  I use it to duplicate
structures or other elements that are not strings.  A pointer to an
element and its size are passed in and the macro returns an allocated
copy of it.

   gcc (GNUs c-compiler) has a neat feature in that it understands
return-values from macros.  I have included a gcc form of these 2 macros
(which makes them a lot more functional) as well as a non-gcc version.

   *NOTE*: I would like to strongly recommend the usage of gcc.  It is
a superior compiler and future releases of this library may require its
use.

Additional Non-Standard Routines.
=================================

   The library has a number of variables and routines that are not a
standard part of most malloc libraries:

`char * malloc_logpath;'
     This variable can be used to set the malloc log filename.  The env
     variable MALLOC_LOGFILE overrides this variable.

`int malloc_errno;'
     This variable stores the internal malloc library error number like
     errno does for the system calls.  It can be passed to
     `malloc_strerror()' (see below) to get a string version of the
     error.  It will have a value of zero if the library has not
     detected any problems.

`void malloc_shutdown(void);'
     This routine shuts the library down and logs the final statistics
     and information especially the non-freed memory pointers.  It
     should be run right before `exit()' or as the last function in
     `main()'.

                  main()
                  {
                          ...
                          malloc_shutdown();
                          exit(0);
                  }

`int malloc_heap_map(void);'
     This routine will log to the logfile (if it is enabled) a graphical
     representation of the current heap space.  It needs some work but
     should provide some good information.

`int malloc_verify(char * pnt);'
     Use `malloc_verify' to verify individual memory pointers that are
     suspect of memory problems.  To check the entire heap pass in a
     NULL or 0 pointer.

     *NOTE*: `malloc_verify' can only check the heap with the functions
     that have been enabled.  For example, if fence-post checking is
     not enabled in the `MALLOC_DEBUG' variable, `malloc_verify' cannot
     check the fence-post areas in the heap.

`int malloc_debug(long debug);'
     With this routine, the value in the `MALLOC_DEBUG' variable can be
     overridden and the library debugging features set explicitly.  For
     instance, if debugging should never be enabled for a program, a
     call to `malloc_debug(0);' as the first call in `main()' will
     disable all the memory debugging from that point on.

     One problem however is that some compilers (gcc for instance) make
     calls to memory allocation functions *before* `main()' is reached
     and `malloc_debug()' called meaning some debugging information may
     be generated regardless.

`int malloc_examine(char * pnt, int * size, char ** file, int * line);'
     This routine provides some very interesting functionality.  It
     returns the size of a pnt's allocation as well as the file and
     line from which it was allocated.

     *NOTE*: This function is *certainly* not portable and is not
     provided by other malloc libraries.

`char * malloc_strerror(int errnum);'
     `malloc_strerror' returns the string representation of the error
     value in errnum (which probably should be malloc_errno).  This
     allows the logging of more verbose memory error messages.

     You can also display the string representation of an error value
     by a call to the `malloc_dbg' program with a `-e #' option
     malloc_dbg program.

How to Compile/Link Without the Library.
========================================

   When you are finished with the development and debugging sessions,
you may want to disable the malloc-debug library and put in its place
either the system's memory-allocation routines, gnu-malloc, or maybe
your own. I have tried to make this a reasonably painless process.  The
ease of the extraction depends heavily on how many of the library's
features your made use of during your coding.

   I am open to any reasonable suggestions as to how to improve this
process while maintaining the effectiveness of the debugging.

   * If you compiled any of your source modules with `MALLOC_FUNC_CHECK'
     defined then you must first recompile all those modules without
     the flag enabled.

   * If you are using any of the special functions provided by the
     malloc-debug library (such as `malloc_shutdown()'), then you will
     need to `#ifdef', remove, or comment them out of your code.

   * If you want to *totally* disable the malloc-debug library then you
     will need to recompile all the C files that include `malloc.h'
     while defining `MALLOC_DEBUG_DISABLE'.  This will cause the malloc
     leap macros to not be applied Allocation macros.

                  gcc -O -g -DMALLOC_DEBUG_DISABLE main.c

   * Now you are ready to relink with a new library.  If you have not
     compiled all your source with `MALLOC_DEBUG_DISABLED' defined then
     you need to include the `malloc_lp.o' file on the link line.

                  gcc -O -g main.o malloc_lp.o -L/usr/local/lib -lgmalloc
     If you have disabled malloc with the `MALLOC_DEBUG_DISABLED' flag
     or never included `malloc.h' in any of your C files, then you will
     not need to include the `malloc_lp.o' file on the link line.

                  gcc -O -g main.o -L/usr/local/lib -lgmalloc
     If you get unresolved references like `_malloc_leap' or
     `_malloc_bcopy' then something was not disabled as it should have
     been.

Information on the Source and General Concerns.
***********************************************

Some Terms and Other Information.
=================================

   Here are a couple definitions and other information for those
interested in "picking the brain" of the library.  The code is a little
ugly here and there and it conforms to the Gray-Watson handbook of
coding standards only.

"bblock"
     basic block containing 2 ^ BASIC_BLOCK bytes of info

"bblock_adm"
     administration for a set of basic blocks

"dblock"
     divided block containing some base 2 number of blocks smaller than
     a basic block.

"dblock_adm"
     administration for a set of divided blocks

"chunk"
     some anonymous amount of memory

General Compatibility Concerns.
===============================

   * Realloc() backwards compatibility with being able to realloc from
     the last freed block is *not* supported.

   * Realloc() of a NULL pointer is supported in which case the library
     will just make a call to malloc().  This is a compilation option
     in the `conf.h' file.

   * The library does *not* provide memalign() nor valloc() support as
     of yet, but may in future releases.  I would be interested to know
     who is using these functions, which architectures they are
     supported on, and for what reason they are being used.

   * Aside from possibly being slower than the system's memory
     allocation functions, the library should be fully compatible with
     the standard memory routines.  If this is *not* the case please
     bring this to my attention.

Issues Important for Porting the Library.
=========================================

   General compatibility issues center around:

   * sbrk or compatible function usages

   * Whether the systems's heap grows towards high or low memory.  The
     chunk.c code is designed (loosely) around the fact that consecutive
     calls to sbrk should give higher memory addresses.

     I have not been able to test the library on a system whose heap
     grows towards low memory.  If you are trying to run the library on
     such a system I would be interested in talking with you.

Soapbox Comments.
*****************

   Since I have your attention I would like to talk for a second about a
couple of things that I feel strongly about.  If you would like any more
information about the below, please mail to the supplied addresses or
drop me a line with any questions.

`The Free Software Foundation <gnu@prep.ai.mit.edu>'
     As you should be able to tell by now, I am a FSF supporter.  The
     FSF's goal, as I see and support it, is to encourage the exchange
     of free source code.  The organization and its individuals have
     volunteered an amazing amount of time toward this.  If you use
     emacs, gcc, gdb, patch, perl, bison, or any of their many programs
     and libraries then you have benefited from the movement.  Please
     consider supporting it.

`Berkeley Software Design, Inc. <bsdi-info@bsdi.com>'
     We at the Antaire Corporation are the proud and enthusiastic
     owners of the BSD/386 operating system.  For $1k you get a
     *complete* BSD-flavor operating system with *full source* for 386
     and 486 systems (binary licenses are available).  Along with the
     obvious benefits of full source code come excellent customer
     support/service and system features such as a MS-DOG runtime
     environment, complete tcp/ip networking facilities including nfs,
     full software development utilities, X, etc.