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

Copyright © 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 see Environment variables.  They should be specified in the user's .mallocrc file see 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 see 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 see 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 see 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 see 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.