The debug memory allocation or dmalloc library has been designed
as a drop in replacement for the system's malloc, realloc,
calloc, free and other memory management routines while
providing powerful debugging facilities configurable at runtime. These
facilities include such things as memory-leak tracking, fence-post write
detection, file/line number reporting, and general logging of
statistics.
The library is reasonably portable having been run successfully on at
least the following operating systems: AIX, BSD/OS, DG/UX, Free/OpenBSD,
HPUX, Irix, Linux, MS-DOG, NeXT, OSF, SCO, Solaris, SunOS, Ultrix,
Unixware, Windoze, and even Unicos on a Cray Y-MP. It also provides
support for the debugging of threaded programs. See Using With Threads.
The package includes the library, configuration scripts, debug utility
application, test program, and documentation. Online documentation as
well as the full source is available at URL http://dmalloc.com/.
Details on the library's mailing list are available there as well.
My contact information is available on the web page. I can be reached
with any questions or feedback. Please include the version number of
the library that you are using as well as your machine and operating
system types.
Gray Watson.
Copying: Library copying and licensing conditions.
Overview: Description of features and how to get started.
Permission to use, copy, modify, and distribute this software for any
purpose and without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies, and
that the name of Gray Watson not be used in advertising or publicity
pertaining to distribution of the document or software without specific,
written prior permission.
Gray Watson makes no representations about the suitability of the
software described herein for any purpose. It is provided "as is"
without express or implied warranty.
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 runtime 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 stored on the stack */
float total;
...
}
main()
{
foo();
}
Heap data is also allocated at runtime and provides a programmer with
dynamic memory capabilities.
main()
{
/* the address is stored on the stack */
char * string;
...
/*
* Allocate a string of 10 bytes on the heap. Store the
* address in string which is on the stack.
*/
string = (char *)malloc(10);
...
/* de-allocate the heap memory now that we're 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 runtime
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.
2.1.2 Functionality Supported by All Malloc Libraries
All malloc libraries support 4 basic memory allocation commands. These
include malloc, calloc, realloc, and free. For
more information about their capabilities, check your system's manual
pages - in unix, do a man 3 malloc.
Function
void *malloc ( unsigned int size )
Usage: pnt = (type *)malloc(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.
Function
void *calloc ( unsigned int number, unsigned int
size )
Usage: pnt = (type *)calloc(number, 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.
Function
void *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 as
much of the information from old_pnt as it can into the
new_pnt space it returns, up to new_size bytes. If there
is a problem allocating this memory, 0L will be returned.
If the old_pnt is 0L then realloc will do the equivalent of a
malloc(new_size). If new_size is 0 and old_pnt is
not 0L, then it will do the equivalent of free(old_pnt) and will
return 0L.
Function
void free ( void *pnt )
Usage: free(pnt)
The free routine releases allocation in pnt which was 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 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 be cast to the appropriate
pointer type for the variable being assigned. Also this may no longer
be necessary on your system, it can still provide some documentation
value to the code.
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.
The debugging features that are available in this debug malloc library
can be divided 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. See Allocation Macros.
return-address information
To debug calls to the library from external sources (i.e. those files
that could not use the allocation macros), some facilities have been
provided to supply the caller's address. This address, with the help of
a debugger, can help you locate the source of a problem. See Return Address.
fence-post (i.e. bounds) checking
Fence-post memory is the area immediately above or below memory
allocations. It is all too 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.
See Fence-Post Overruns.
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, the tests will verify that everything is okay but may not
inform the user of problems in a graceful manner.
logging statistics
One of the reasons why the debug malloc library was initially developed
was to track programs' memory usage - specifically to locate
memory leaks which are places where allocated memory is never
getting freed. See Memory Leaks.
The library has a number of logging capabilities that can track un-freed
memory pointers as well as runtime memory usage, memory transactions,
administrative actions, and final statistics.
examining unfreed memory
Another common problem happens when a program frees a memory pointer but
goes 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 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. The library can
either stop after dumping core or continue running.
NOTE: do not be surprised if the library catches problems with
your system's routines. It took me hours to finally come to the
conclusion that the localtime call, included in SunOS release 4.1,
overwrites one of its fence-post markers.
To configure, compile, and install the library, follow these steps
carefully.
Make sure you have the latest version of the library available
from the home page http://dmalloc.com/.
You probably will want to edit the settings in
settings.dist to tune specific features of the library. The
configure script will copy this file to settings.h
which is where you should be adding per-architecture settings.
Type sh ./configure to configure the library. You may want
to first examine the config.help file for some information about
configure. You may want to use the --disable-cxx option if you do
not want the Makefile to build the C++ version of dmalloc. You may want
to use the --enable-threads option to build the threaded version
of dmalloc. You may want to use the --enable-shlib option to
build the shared versions of the dmalloc libraries. Configure should
generate the Makefile and configuration files automatically.
NOTE: It seems that some versions of tr (especially from HP-UX)
don't understand tr '[a-z]' '[A-Z]'. Since configure uses tr
often, you may need to either get GNU's tr (in their textutils package)
or generate the Makefile and conf.h files by hand.
You may want to examine the Makefile and conf.h files
created by configure to make sure it did its job correctly.
You might want to tune the settings in settings.h file to
tune the library to the local architecture. This file contains relevant
settings if you are using pthreads or another thread library.
See Using With Threads. The configure script created this
file from the settings.dist file. Any permanent changes to these
settings should made to the settings.dist file. You then can run
config.status to re-create the settings.h file.
The DMALLOC_SIZE variable gets auto-configured in
dmalloc.h.2 but it may not generate correct settings for all
systems. You may have to alter the definitions in this file to get
things to stop complaining when you go to compile about the size
arguments to malloc routines. Comments on this please.
Typing make should be enough to build libdmalloc.a,
libdmalloclp.a, and dmalloc program. If it does not work,
please see if there are any notes in the contrib directory about your
system-type. If not and you figure your problem out, please send me
some notes so future users can profit from your experiences.
NOTE: You may experience some errors compiling some of the
return.h assembly macros which attempt to determine the callers address
for logging purposes. You may want to first try disabling any compiler
optimization flags. If this doesn't work then you may need to disable
the USE_RETURN_MACROS variable in the settings.h file.
NOTE: The code is dependent on an ANSI-C compiler. If the
configure script gives the WARNING that you do not have an ANSI-C
compiler, you may still be able to add some sort of option to your
compiler to make it ANSI. If there such is an option, please send it to
the author so it can be added to the configure script.
If you use threads, typing make threads should be enough
to build libdmallocth.a which is the threaded version of the
library. This may or may not work depending on the configuration
scripts ability to detect your local thread functionality. Feel free to
send me mail with improvements.
See the "Using With Threads" section for more information about the
operation of the library with your threaded program. See Using With Threads.
If you have a C++ compiler installed, the library should have
automatically built libdmallocxx.a which is the C++ version of
the library. If it was not done automatically, you can build it by
typing make cxx. You should link this library into your C++
programs instead of libdmalloc.a. See the dmallocc.cc C++
file which contains basic code to overload the new, new[],
delete, and delete[] C++ operators. My apologies on the
minimal C++ support. I am still living in a mostly C world. Any help
improving this interface without sacrificing portability would be
appreciated.
Typing make tests should build the dmalloc_t test
program.
Typing make light should run the dmalloc_t test
program through a set of light trials. By default this will execute
dmalloc_t 5 times - each time will execute 10,000 malloc
operations in a very random manner. Anal folks can type make
heavy to up the ante. Use dmalloc_t --usage for the list of all
dmalloc_t options.
Typing make install should install the libdmalloc.a
and libdmalloc_lp.a library files in /usr/local/lib, the
dmalloc.h include file in /usr/local/include, and the
dmalloc utility in /usr/local/bin. You may also want to
type make installth to install the thread library into place
and/or make installcc to install the C++ library into place.
You may have specified a --prefix=PATH option to configure in
which case /usr/local will have been replaced with PATH.
See the "Getting Started" section to get up and running with the
library. See Getting Started.
This section should give you a quick idea on how to get going.
Basically, you need to do the following things to make use of the
library:
Make sure you have the latest version of the library available
from the home page http://dmalloc.com/.
Follow the installation instructions on how to configure and
make and install the library (i.e. type: make install).
See Installation.
You need to make sure that the dmalloc building process
above was able to locate one of the the on_exit or atexit
functions. If so, then the dmalloc library should be able to
automatically call dmalloc_shutdown when exit is called.
This causes the memory statistics and unfreed information to be dumped
to the log file. However, if your system has neither, you will need to
call dmalloc_shutdown yourself before your program exits.
Add an alias for dmalloc to your shell's rc file if supported.
Bash, ksh, and zsh users should add the following to their
.bashrc, .profile, or .zshrc file respectively
(notice the -b option for bourne shell output):
function dmalloc { eval `command dmalloc -b $*`; }
By the way, if you are looking for a shell, I heartily recommend trying
out zsh. It is a bourne shell written from scratch with much the same
features as tcsh without the csh crap. If you are still using
csh or tcsh, you should add the following to your .cshrc file
(notice the -C option for c-shell output):
alias dmalloc 'eval `\dmalloc -C \!*`'
Although not necessary, you may want to include dmalloc.h
in your C files and recompile. This will allow the library to report
the file/line numbers of calls that generate problems. See Allocation Macros. It should be inserted at the bottom of your include
files as to not conflict with other includes. You may want to ifdef it
as well and compile with cc -DDMALLOC ...:
/* other includes above ^^^ */
#ifdef DMALLOC
#include "dmalloc.h"
#endif
Link the dmalloc library into your program.
Enable the debugging features by typing dmalloc -l logfile
-i 100 low (for example). This will:
set the malloc log path to logfile (-l logfile)
have the library check itself every 100 iterations (-i 100)
enable a number of debug features (low). You can
also try runtime for minimal checking or medium or
high for more extensive heap verification. all is also
provided but generates a multitude of log messages without many more
tests.
dmalloc --usage will provide verbose usage info for the dmalloc
program. See Dmalloc Program.
You may also want to install the dmallocrc file in your home
directory as .dmallocrc. This allows you to add your own
combination of debug tokens. See RC File.
You may also want to enable the log-unknown token
(dmalloc -p log-unknown) which will log non-freed information
about "unknown" memory to the log file. Unknown means memory that
does not have associated file and line information. This is necessary
if you are not including dmalloc.h in your C files or if
you want to track possible memory leaks in system functions.
Run your program, examine the logfile that should have been created by
dmalloc_shutdown, and use its information to help debug your program.
See the next section for help with this. See Troubleshooting.
This section provides some answers to some common problems and
questions. Please feel free to send me mail with any additions to this
list - either problems you are still having or tips that you would like
to pass on.
Why does my program run so slow?
This library has never been (and maybe never will be) optimized for
space nor speed. Some of its features make it unable to use some of the
organizational methods of other more efficient heap libraries. If you
have the check-heap token enabled, see the -i option to the
dmalloc utility. See Dmalloc Program.
Why was a log-file not produced after I ran my program?
This could be caused by a number of different problems.
Are you sure you followed all of the items in the "Getting Started"
section? Please review them if there is any doubt. See Getting Started.
Use the env or printenv commands to make sure that
the DMALLOC_OPTIONS variable is set in your exported environment.
See Environment Variable.
Make sure that your program has been compiled correctly with the
dmalloc library. The ident program should show chunk.c and other
dmalloc files compiled into your program. You can also do strings
-a your-program | grep chunk.c and look for something like $Id:
chunk.c,v 1.152 1999/08/25 12:37:01 gray Exp $ with different versions
and date information. If this doesn't show up then chances are dmalloc
was not linked into your program.
If your program changes its working directory, it may write the
dmalloc log-file somewhere else in the filesystem. You will need to
check both where the program was started and to where it might change
directory.
I don't see any information about my non-freed (leaked) memory?
The library will not (by default) report on "unknown" non-freed
memory. Unknown means memory that does not have associated file and
line information. To log information about unknown pointers you should
enable the log-unknown token (dmalloc -p log-unknown).
This will be necessary if you are not including dmalloc.h
in all of your C files or if you are interested in tracking leaks in
system functions.
By including dmalloc.h in your C files, your calls to malloc,
calloc, realloc, recalloc, memalign, valloc, strdup, and free are
replaced with calls to _malloc_leap, _calloc_leap, _realloc_leap,
_recalloc_leap, _memalign_leap, _valloc_leap, _strdup_leap, and
_free_leap. Additionally the library replaces calls to xmalloc,
xcalloc, xrealloc, xrecalloc, xmemalign, xvalloc, xstrdup, and xfree
with associated _leap calls.
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 problems.
not freed: '0x38410' (22 bytes) from 'dmalloc_t.c:92'
This line from a log file shows that memory was not freed from file
dmalloc_t.c line 92. See Memory Leaks.
You may notice some non standard memory allocation functions in the
above leap list. Recalloc is a routine like realloc that reallocates
previously allocated memory to a new size. If the new memory size is
larger than the old, recalloc initializes the new space to all zeros.
This may or may not be supported natively by your operating system.
Memalign is like malloc but should insure that the returned pointer is
aligned to a certain number of specified bytes. Currently, the memalign
function is not supported by the library. It defaults to returning
possibly non-aligned memory for alignment values less than a block-size.
Valloc is like malloc but insures that the returned pointer will be
aligned to a page boundary. This may or may not be supported natively
by your operating system but is fully supported by the library. Strdup
is a string duplicating routine which takes in a null terminated string
pointer and returns an allocated copy of the string that will need to be
passed to free later to deallocate.
The X versions of the standard memory functions (xmalloc, xfree, etc.)
will print out an error message to standard error and will stop if the
library is unable to allocate any additional memory. It is useful to
use these routines instead of checking everywhere in your program for
allocation routines returning NULL pointers.
WARNING: If you are including the dmalloc.h file in your
sources, it is recommended that it be at the end of your include file
list because dmalloc uses macros and may try to change declarations of
the malloc functions if they come after it.
Even though the allocation macros can provide file/line information for
some of your code, there are still modules which either you can't
include dmalloc.h (such as library routines) or you just don't
want to. You can still get information about the routines that call
dmalloc function from the return-address information. To accomplish
this, you must be using this library on one of the supported
architecture/compilers. See Portability.
The library attempts to use some assembly hacks to get the the
return-address or the address of the line that called the dmalloc
function. If you have the log-unknown token enabled and you run
your program, you might see the following non-freed memory messages.
not freed: '0x38410' (22 bytes) from 'ra=0xdd2c'
not freed: '0x38600' (10232 bytes) from 'ra=0x10234d'
not freed: '0x38220' (137 bytes) from 'ra=0x82cc'
With the help of a debugger, these return-addresses (or ra) can then be
identified. I've provided a ra_info.pl perl script in the
contrib/ directory with the dmalloc sources which seems to work
well with gdb. You can also use the manual methods below for gdb.
(gdb) x 0x10234d
0x10234d <_findbuf+132>: 0x7fffceb7
(gdb) info line *(0x82cc)
Line 1092 of argv.c starts at pc 0x7540 and ends at 0x7550.
In the above example, gdb was used to find that the two non-freed memory
pointers were allocated in _findbuf() and in file argv.c line
1092 respectively. The x address (for examine) can always be
used on the return-addresses but the info line *(address) will
only work if that file was compiled using the -g option and has
not been stripped. This limitation may not be true in later versions of
gdb.
One potential problem with the library and its multitude of checks and
diagnoses is that they only get performed when a dmalloc function is
called. One solution this is to include dmalloc.h and compile
your source code with the DMALLOC_FUNC_CHECK flag defined and
enable the check-funcs token. See Debug Tokens.
cc -DDMALLOC_FUNC_CHECK file.c
NOTE: Once you have compiled your source with DMALLOC_FUNC_CHECK
enabled, you will have to recompile with it off to disconnect the
library. See Disabling the Library.
WARNING: You should be sure to have dmalloc.h included at
the end of your include file list because dmalloc uses macros and may
try to change declarations of the checked functions if they come after
it.
When this is defined dmalloc will override a number of functions and
will insert a routine which knows how to check its own arguments and
then call the real function. Dmalloc can check such functions as
bcopy, index, strcat, and strcasecmp. For
the full list see the end of dmalloc.h.
When you call strlen, for instance, dmalloc 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, dmalloc
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 dmalloc does not know anything about it.
The library has a number of variables that are not a standard part of
most malloc libraries:
char * dmalloc_logpath
This variable can be used to set the dmalloc log filename. The env
variable DMALLOC_LOGFILE overrides this variable.
int dmalloc_errno
This variable stores the internal dmalloc library error number like errno
does for the system calls. It can be passed to dmalloc_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.
int dmalloc_address
This variable holds the address to be specifically looked for when
allocating or freeing by the library.
int dmalloc_address_count
This variable stores the argument to the address library setting. If it
is set to a greater than 0 value then after the library has seen the
addr address this many times, it will call
dmalloc_error().
This works well in conjunction with the STORE_SEEN_COUNT option.
See Memory Leaks.
Additionally the library provides a number of non-standard malloc
routines:
Function
void dmalloc_shutdown ( void )
This function shuts the library down and logs the final statistics and
information especially the non-freed memory pointers. The library has
code to support auto-shutdown if your system has on_exit() or
atexit() calls (see conf.h). If you do not have these
routines, then dmalloc_shutdown should be called right before
exit() or as the last function in main().
main()
{
...
dmalloc_shutdown();
exit(0);
}
Function
void dmalloc_log_heap_map ( void )
This routine logs to the logfile (if it is enabled) a graphical
representation of the current heap space.
Function
void dmalloc_log_stats ( void )
This routine outputs the current dmalloc statistics to the log file.
Function
void dmalloc_log_unfreed( void )
This function dumps the unfreed-memory information to the log file.
This is also useful to dump the currently allocated points to the log
file to be compared against another dump later on.
Function
int dmalloc_verify ( char * pnt )
This function verifies individual memory pointers that are suspect of
memory problems. To check the entire heap pass in a NULL or 0 pointer.
The routine returns DMALLOC_VERIFY_ERROR or DMALLOC_VERIFY_NOERROR.
NOTE: dmalloc_verify() can only check the heap with the
functions that have been enabled. For example, if fence-post checking
is not enabled, dmalloc_verify() cannot check the fence-post
areas in the heap.
Function
void dmalloc_debug ( long debug )
This routine overrides the debug setting from the environment variable
and sets the library debugging features explicitly. For instance, if
debugging should never be enabled for a program, a call to
dmalloc_debug(0) as the first call in main() will disable
all the memory debugging from that point on.
One problem however is that some systems make calls to memory allocation
functions beforemain() is reached therefore before
dmalloc_debug() can be called meaning some debugging information
may be generated regardless.
Function
long dmalloc_debug_current ( void )
This routine returns the current debug value from the environment
variable. This allows you to save a copy of the debug dmalloc settings
to be changed and then restored later.
Function
int dmalloc_examine ( char * pnt, int * size,
char ** file, int * line, void ** ret_address )
This function returns the size of a pointer's allocation as well as the
file and line or the return-address from where it was allocated. It
will return NOERROR or ERROR depending on whether pnt is good or not.
NOTE: This function is certainly not provided by most if
not all other malloc libraries.
Function
void dmalloc_message ( char * format, ... )
Write a message into the dmalloc logfile using printf-like arguments.
NOTE: this is only available is STDARG is defined by the library
and you have the stdarg.h include file.
Function
void dmalloc_vmessage ( char * format, va_list args )
Write a message into the dmalloc logfile using vprintf-like arguments.
NOTE: this is only available is STDARG is defined by the library
and you have the stdarg.h include file.
Function
void dmalloc_track ( dmalloc_track_t track_func )
Register an allocation tracking function which will be called each time
an allocation occurs. Pass in NULL to disable. To take a look at what
information is provided, see the dmalloc_track_t function typedef in
dmalloc.h.
Function
unsigned long dmalloc_mark ( void )
Return to the caller the current "mark" which can be used later to
dmalloc_log_changed pointers since this point. Multiple marks can be
saved and used.
Function
unsigned long dmalloc_log_changed ( unsigned long mark,
int not_freed_b, int freed_b, int details_b )
Dump the pointers that have changed since the mark which was returned by
dmalloc_mark. If not_freed_b is set to non-0 then log the new pointers
that are non-freed. If free_b is set to non-0 then log the new pointers
that are freed. If details_b set to non-0 then dump the individual
pointers that have changed otherwise just dump the summaries.
Function
const char * dmalloc_strerror ( int errnum )
This function returns the string representation of the error value in
errnum (which probably should be dmalloc_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 dmalloc program with a -e # option.
See Dmalloc Program.
For those people using the C++ language, some special things need to be
done to get the library to work. The problem exists with the fact that
the dynamic memory routines in C++ are new() and delete()
as opposed to malloc() and free().
The file dmallocc.cc is provided in the distribution which
effectively redirects new to the more familiar malloc and
delete to the more familiar free. Compile and link this
file in with the C++ program you want to debug.
NOTE: The author is not a C++ hacker so feedback in the form of
other hints and ideas for C++ users would be much appreciated.
When you are finished with the development and debugging sessions, you
may want to disable the dmalloc library and put in its place either the
system's memory-allocation routines, gnu-malloc, or maybe your own.
Attempts have been made 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.
Reasonable suggestions are welcome as to how to improve this process
while maintaining the effectiveness of the debugging.
If you want to totally disable the dmalloc library then you will
need to recompile all the C files that include dmalloc.h while
defining DMALLOC_DISABLE. This will cause the dmalloc leap
macros to not be applied. See Allocation Macros.
cc -g -DDMALLOC_DISABLE main.c
If you compiled any of your source modules with DMALLOC_FUNC_CHECK
defined then you must first recompile all those modules without the flag
enabled.
If you have not compiled all your source with DMALLOC_DISABLED
defined then you need to link your program with the
libdmalloclp.a library.
cc main.o -L/usr/local/lib -ldmalloclp -lgmalloc
If you have disabled dmalloc with the DMALLOC_DISABLED flag or
never included dmalloc.h in any of your C files, then you will
not need the libdmalloclp.a library.
cc -g main.o -L/usr/local/lib -lgmalloc
If you get unresolved references like _malloc_leap or
_dmalloc_bcopy then something was not disabled as it should have
been.
Here are a number of possible scenarios for using the dmalloc library to
track down problems with your program.
You should first enable a logfile filename (I use dmalloc) and
turn on a set of debug features. You can use dmalloc -l dmalloc
low to accomplish this. If you are interested in having the error
messages printed to your terminal as well, enable the print-error
token by typing dmalloc -p print-error afterwards. See Dmalloc Program.
Now you can enter your debugger (I use the excellent GNU debugger
gdb), and put a break-point in dmalloc_error() which is the
internal error routine for the library. When your program is run, it
will stop there if a memory problem is detected.
If you are using GDB, I would recommend adding the contents of
dmalloc.gdb in the contrib subdirectory to your
.gdbinit file in your home directory. This enables the
dmalloc command which will prompt you for the arguments to the
dmalloc command and will set a break point in dmalloc_error()
automatically.
General Errors: Diagnosing general problems with a debugger.
If your program stops at the dmalloc_error() routine then one of
a number of problems could be happening. Incorrect arguments could have
been passed to a malloc call: asking for negative number of bytes,
trying to realloc a non-heap pointer, etc.. There also could be a
problem with the system's allocations: you've run out of memory, some
other function in your program is using sbrk, etc. However, it
is most likely that some code that has been executed was naughty.
To get more information about the problem, first print via the debugger
the dmalloc_errno variable to get the library's internal error code.
You can suspend your debugger and run dmalloc -e
value-returned-from-print to get an English translation of the error.
A number of the error messages are designed to indicate specific
problems with the library administrative structures and may not be
user-friendly.
If the problem was due to the arguments or system allocations then the
source of the problem has been found. However, if some code did
something wrong, you may have some more work to do to locate the actual
problem. The check-heap token should be enabled and the interval
setting disabled or set to a low value so that the library can find the
problem as close as possible to its source. The code that was execute
right before the library halted, can then be examined closely for
irregularities. See Debug Tokens, See Dmalloc Program.
You may also want to put calls to dmalloc_verify(0) in your code
before the section which generated the error. This should locate the
problem faster by checking the library's structures at that point.
See Extensions.
So you've run your program, examined the log-file and discovered (to
your horror) some un-freed memory. Memory leaks can become large
problems since even the smallest and most insignificant leak can starve
the program given the right circumstances.
not freed: '0x45008' (12 bytes) from 'ra=0x1f8f4'
not freed: '0x45028' (12 bytes) from 'unknown'
not freed: '0x45048' (10 bytes) from 'argv.c:1077'
known memory not freed: 1 pointer, 10 bytes
unknown memory not freed: 2 pointers, 24 bytes
Above you will see a sample of some non-freed memory messages from the
logfile. In the first line the 0x45008 is the pointer that was
not freed, the 12 bytes is the size of the unfreed block, and the
ra=0x1f8f4 or return-address shows where the allocation
originated from. See Return Address.
The systems which cannot provide return-address information show
unknown instead, as in the 2nd line in the sample above.
The argv.c:1077 information from the 3rd line shows the file and
line number which allocated the memory which was not freed. This
information comes from the calls from C files which included
dmalloc.h. See Allocation Macros.
At the bottom of the sample it totals the memory for you and breaks it
down to known memory (those calls which supplied the file/line
information) and unknown (the rest).
Often, you may allocate memory in via strdup() or another
routine, so the logfile listing where in the strdup routine the
memory was allocated does not help locate the true source of the memory
leak - the routine that called strdup. Without a mechanism to
trace the calling stack, there is no way for the library to see who the
caller of the caller (so to speak) was.
However, there is a way to track down unfreed memory in this
circumstance. You need to compile the library with
STORE_SEEN_COUNT defined in conf.h. The library will then
record how many times a pointer has been allocated or freed. It will
display the unfreed memory as:
not freed: '0x45008|s3' (12 bytes) from 'ra=0x1f8f4'
The STORE_SEEN_COUNT option adds a |s# qualifier to the
address. This means that the address in question was seen # many
times. In the above example, the address 0x45008 was seen
3 times. The last time it was allocated, it was not freed.
How can a pointer be "seen" 3 times? Let say you strdup a
string of 12 characters and get address 0x45008 - this is #1
time the pointer is seen. You then free the pointer (seen #2) but later
strdup another 12 character string and it gets the 0x45008
address from the free list (seen #3).
So to find out who is allocating this particular 12 bytes the 3rd time,
try dmalloc -a 0x45008:3. The library will stop the program the
third time it sees the 0x45008 address. You then enter a
debugger and put a break point at dmalloc_error. Run the program
and when the breakpoint is reached you can examine the stack frame to
determine who called strdup to allocate the pointer.
To not bother with the STORE_SEEN_COUNT feature, you can also run
your program with the never-reuse token enabled. This token will
cause the library to never reuse memory that has been freed. Unique
addresses are always generated. This should be used with caution since
it may cause your program to run out of memory.
For a definition of fence-posts please see the "Features" section.
See Features.
If you have encountered a fence-post memory error, the logfile should be
able to tell you the offending address.
free: failed UNDER picket-fence magic-number checking:
pointer '0x1d008' from 'dmalloc_t.c:427'
Dump of proper fence-bottom bytes: '\e\253\300\300\e\253\300\300'
Dump of '0x1d008'-8: '\e\253\300\300WOW!\003\001pforger\023\001\123'
The above sample shows that the pointer 0x1d008 has had its lower
fence-post area overwritten. This means that the code wrote below the
bottom of the address or above the address right below this one. In the
sample, the string that did it was WOW!.
The library first shows you what the proper fence-post information
should look like, and then shows what the pointer's bad information was.
If it cannot print the character, it will display the value as
\ddd where ddd are three octal digits.
By enabling the check-heap debugging token and assigning the
interval setting to a low number, you should be able to locate
approximately when this problem happened. See Debug Tokens,
See Dmalloc Program.
This is the newest section of the library and therefore contains the
least information about a subject on which I probably could write a
book. My apologies.
Threads are special operating system facilities which allow your
programs to have multiple threads of execution (hence the name). In
effect your program can be doing a number of things "at the same
time". This allows you to take full advantage of modern operating
system scheduling and multi-processor hardware. If I've already lost
you or if any of the terminology below does not make sense, see manuals
about POSIX threads (pthreads) before going any further. O'Reilly
publishes a pretty good pthreads manual for example.
The support for threads in dmalloc is minimal although probably adequate
for most if not all testing scenarios. It provides support for mutex
locking itself to protect against race conditions that result in
multiple simultaneous execution. One of the major problems is that most
thread libraries uses malloc themselves. Since all of dmalloc's
initialization happens when a call to malloc is made, we may be
attempting to initialize or lock the mutex while the thread library is
booting up. A baaaad thing since thread libraries aren't reentrant.
The solution to this problem is to have the library not initialize or
lock its mutex variable until after a certain number of allocation calls
have been completed. If the library does not wait before initializing
the locks, the thread library will probably core dump. If it waits too
long then it can't protect itself from multiple execution and it will
abort or other bad things might happen. You adjust the number of times
to wait at runtime with the "lock-on" option to the dmalloc program
(for example dmalloc -o 20). See Dmalloc Program. Times
values between 2 and 30 are probably good although operating systems
will vary significantly. You know its too low if your program core
dumps and too high if the library generates an exception.
An additional complexity is when we are initializing the lock before
mutex locking around the library. As mentioned, the initialization
itself may generate a malloc call causing the library to go recursive
and the pthread library to possibly core dump. With the THREAD_INIT_LOCK
setting defined in settings.h, you can tune how many times before
we start locking to try and initialize the mutex lock. It defaults to 2
which seems to work for me. If people need to have this runtime
configurable or would like to present an alternative default, please let
me know.
To build the library with the threaded stubs type make threads
which should build libdmallocth.a. The auto-configurations for
these functions is in its infancy and may or may not work depending on
the script's ability to detect your local thread functionality. Feel
free to send me mail with comments or improvements to them.
So that's it. If you have any specific questions or would like addition
information posted in this section, please let me know. Experienced
thread programmers only please.
The dmalloc program is designed to assist in the setting of the
environment variable DMALLOC_OPTIONS. See Environment Variable. 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 dmalloc should be sent
through the eval shell command which will do the commands.
Shell Alias: Using a shell alias with the utility.
The dmalloc program is designed to assist in the setting of the
environment variable DMALLOC_OPTIONS. See Environment Variable. 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 dmalloc should be sent
through the eval shell command which will do the commands.
With shells that have aliasing or macro capabilities: csh, bash, ksh,
tcsh, zsh, etc., setting up an alias to dmalloc to do the eval call is
recommended. Bash, ksh, and zsh users should add the following to their
.bashrc, .profile, or .zshrc file respectively
(notice the -b option for bourne shell output):
function dmalloc { eval `command dmalloc -b $*`; }
If you are still using csh or tcsh, you should add the following
to your .cshrc file (notice the -C option for c-shell
output):
alias dmalloc 'eval `\dmalloc -C \!*`'
This allows the user to execute the dmalloc command as dmalloc
arguments.
Users of versions of the Bourne shell (usually known as /bin/sh) that
don't have command functions will need to send the output to a temporary
file and the read it back in with the "." command:
The most basic usage for the program is dmalloc [-bC] tag. The
-b or -C (either but not both flags used at a time) are
for generating Bourne or C shell type commands respectively. dmalloc
will try and use the SHELL environment variable to determine
whether bourne or C shell commands should be generated but you may want
to explicitly specify the correct flag.
The tag argument to dmalloc should match a line from the user's
runtime configuration file or should be one of the built-in tags.
See RC File. If no tag is specified and no other option-commands
used, dmalloc will display the current settings of the environment
variable. It is useful to specify one of the verbose options when doing
this.
To find out the usage for the debug malloc program try dmalloc
--usage-long. The standardized usage message that will be displayed is
one of the many features of the argv library included with this package.
Here is a detailed list of the flags that can passed to dmalloc:
-a address
Set the addr part of the DMALLOC_OPTIONS variable to
address (or alternatively address:number).
-b
Output Bourne shell type commands.
-C
Output C shell type commands.
-c
Clear/unset all of the settings not specified with other arguments. You
can do this automatically when you set to a new tag with the -r
option.
NOTE: clear will never unset the debug setting. Use
-d 0 or a tag to none to achieve this.
-d bitmask
Set the debug part of the DMALLOC_OPTIONS env variable to
the bitmask value which should be in hex. This is overridden (and
unnecessary) if a tag is specified.
-D
List all of the debug-tokens. Useful for finding a token to be used
with the -p or -m options. Use with -v or -V
verbose options.
-e errno
Print the dmalloc error string that corresponds to the error number
errno.
-f filename
Use this configuration file instead of the RC file
$HOME/.dmallocrc.
-i number
Set the checking interval to number. If the check-heap token is
enabled, this causes the library to only check the heap every Nth time
which can significantly increase the running speed of your
program. If a problem is found, however, this limits your ability to
determine when the problem occurred. Try values of 50 or 100 initially.
-k
Do not reset all of the settings when a tag is specified. This
specifically overrides the -r option and is provided here to
override -r if it has been added to the dmalloc alias.
-l filename
Write the debugging output and other log-file information to filename.
-L
Output the debug-value not in hex but by individual debug-tokens in long
form.
-m token(s)
Remove (minus) the debug capabilities of token(s) from the current debug
setting or from the selected tag (or -d value). Multiple -m
options can be specified.
-n
Without changing the environment, output the commands resulting from the
supplied options.
-o times
Set the "lock-on" period which dictates with the threaded version of
the library to not initialize or lock the mutex lock around the library
until after a certain number of allocation calls have been made. Some
number between 2 and 30 is probably good. See the "Using With
Threads" section for more information about the operation of the
library with threads. See Using With Threads.
-p token(s)
Add (plus) the debug capabilities of token(s) to the current debug
setting or to the selected tag (or -d value). Multiple -p
options can be specified.
-r
Remove (unset) all settings when using a tag. This is useful when you
are returning to a standard development tag and want the logfile,
address, and interval settings to be cleared automatically. If you want
this behavior by default, this can be put into the dmalloc alias.
-s number
Set the start part of the DMALLOC_OPTIONS env variable to
number (alternatively file:line).
-S
Output the debug-value not in hex but by individual debug-tokens in short
form.
-t
List all of the tags in the rc-file. Use with -v or -V
verbose options.
-v
Give verbose output. Especially useful when dumping current settings or
listing all of the tags.
If no arguments are specified, dmalloc dumps out the current settings
that you have for the environment variable. For example:
# start tough debugging, check the heap every 100 times,
# send the log information to file 'dmalloc'
dmalloc high -i 100 -l dmalloc
# find out what error code 20 is (from the logfile)
dmalloc -e 20
# cause the library to halt itself when it sees the address 0x34238
# for the 6th time.
dmalloc -a 0x34238:6
# return to the normal 'runtime' settings and clear out all
# other settings
dmalloc -c runtime
# enable basic 'low' settings plus (-p) the logging of
# transactions (log-trans) to file 'dmalloc'
dmalloc low -p log-trans -l dmalloc
# print out the current settings with Very-verbose output
dmalloc -V
# list the available debug malloc tokens with Very-verbose output
dmalloc -DV
# list the available tags from the rc file with verbose output
dmalloc -tv
An environment variable is a variable that is part of the user's
working environment and is shared by all the programs. The
DMALLOC_OPTIONS variable is used by the dmalloc library to enable
or disable the memory debugging features, at runtime. It can be set
either by hand or with the help of the dmalloc program. See Dmalloc Program.
To set it by hand, Bourne shell (sh, bash, ksh, or zsh) users should use:
DMALLOC_OPTIONS=value
export DMALLOC_OPTIONS
C shell (csh or tcsh) users need to invoke:
setenv DMALLOC_OPTIONS value
The value in the above examples is a comma separated list of tokens each
having a corresponding value. The tokens are described below:
debug
This should be set to a value in hexadecimal which corresponds to the
functionality token values added together. See Debug Tokens. For
instance, if the user wanted to enable the logging of memory
transactions (value 0x008) and wanted to check fence-post memory
(value 0x400) then debug should be set to 0x408
(0x008 + 0x400).
NOTE: You don't have to worry about remembering all the hex
values of the tokens because the dmalloc program automates the setting
of this variable especially.
NOTE: You can also specify the debug tokens directly, separated
by commas. See Debug Tokens. If debug and the tokens are
both used, the token values will be added to the debug value.
lockon
Set this to a number which is the "lock-on" period. This dictates
with the threaded version of the the library to not initialize or lock
the mutex lock around the library until after a certain number of
allocation calls have been made. See the "Using With Threads" section
for more information about the operation of the library with threads.
See Using With Threads.
log
Set this to a filename so that if 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.
To get different logfiles for different processes, you can assign
log to a string with %d in it (for instance
logfile.%d). This will be replaced with the pid of the running
process (for instance logfile.2451).
WARNING: it is easy to core dump any program with dmalloc, if
you send in a format with arguments other than the one %d.
addr
When this is set to a hex address (taken from the dmalloc log-file for
instance) dmalloc 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. By setting the number argument to
0, the program will never stop when it sees the address. This is useful
for logging all activity on the address and makes it easier to track
down specific addresses not being freed.
This works well in conjunction with the STORE_SEEN_COUNT option.
See Memory Leaks.
NOTE: dmalloc will also log all activity on this address along
with a count.
inter
By setting this to a number X, dmalloc will only check the heap every X
times. This means a number of debugging features can be enabled while
still running the program within a finite amount of time.
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.
start
Set this to a number X and dmalloc will begin checking the heap after X
times. This means the intensive debugging can be started after a
certain point in a program.
start also has the format file:line. For instance, if it is set
to dmalloc_t.c:126 dmalloc will start checking the heap after it
sees a dmalloc call from the dmalloc_t.c file, line number 126.
If line number is 0 then dmalloc will start checking the heap after it
sees a call from anywhere in the dmalloc_t.c file.
This allows the intensive debugging to be started after a certain
routine or file has been reached in the program.
Some examples are:
# turn on transaction and stats logging and set 'malloc' as the log-file
setenv DMALLOC_OPTIONS log-trans,log-stats,log=malloc
# enable debug flags 0x1f as well as heap-checking and set the interval
# to be 100
setenv DMALLOC_OPTIONS debug=0x1f,check-heap,inter=100
# enable 'malloc' as the log-file, watch for address '0x1234', and start
# checking when we see file.c line 123
setenv DMALLOC_OPTIONS log=malloc,addr=0x1234,start=file.c:123
The below tokens and their corresponding descriptions are for the
setting of the debug library setting in the environment variable.
See Environment Variable. They should be specified in the user's
.dmallocrc file. See RC File.
Each token, when specified, enables a specific debugging feature. For
instance, if you have the log-stats token enabled, the library will log
general statistics to the logfile.
To get this information on the fly, use dmalloc -DV. This will
print out the Debug tokens in Very-verbose mode. See Dmalloc Program.
none
No debugging functionality
log-stats
Log general statistics when dmalloc_shutdown or dmalloc_log_stats is
called.
log-non-free
Log non-freed memory pointers when dmalloc_shutdown or dmalloc_log_unfreed
is called.
log-thread-id
For systems that have multi-threaded programs (don't worry if this does
not make sense to you), log thread-id for allocated pointer (see
conf.h).
log-trans
Log general memory transactions (quite verbose).
log-stamp
Log a time stamp for all messages.
log-admin
Log administrative information (quite verbose).
log-blocks
Log detailed block information when dmalloc_log_heap_map is called.
log-unknown
Like log-non-free but logs non-freed memory pointers that did not have
file/line information associated with them.
log-bad-space
Log actual bytes in and around bad pointers.
log-nonfree-space
Log actual bytes in non-freed pointers.
log-elapsed-time
Log elapsed-time for allocated pointers (see conf.h).
log-current-time
Log current-time for allocated pointers (see conf.h).
check-fence
Check fence-post memory areas.
check-heap
Verify heap administrative structure.
check-lists
Examine internal heap linked-lists.
check-blank
Check to see if space that was blanked by free-blank or alloc-blank has
been overwritten. If this is enabled then it will enable free-blank and
alloc-blank automatically.
check-funcs
Check the arguments of some functions (mostly string operations) looking
for bad pointers.
force-linear
Have the heap complain when additional program functionality seems to
have made use of the system's heap-allocation routine sbrk
directly behind the dmalloc library's back. This is disabled by default
since an increasing number of operating system functions seem to be
doing this, especially pthreads packages.
catch-signals
Shutdown the library automatically on SIGHUP, SIGINT, or SIGTERM. This
will cause the library to dump its statistics (if requested) when you
press control-c on the program (for example).
realloc-copy
Always copy data to a new pointer when realloc.
free-blank
Write special bytes (decimal 197, octal 0305, hex 0xc5) into space when
it is freed. The same bytes are written when memory is allocated if
alloc-blank is enabled.
error-abort
Abort the program (and dump core) on errors. See error-dump below.
alloc-blank
Write special bytes (decimal 197, octal 0305, hex 0xc5) into space when
it is allocated. The same bytes are written when memory is freed if
free-blank is enabled.
heap-check-map
Log a heap-map to the logfile every time the heap is checked.
print-messages
Log any errors and messages to the screen via standard-error.
catch-null
Abort the program immediately if the library fails to get more heap
space from sbrk.
never-reuse
Have the heap never use space that has been used before and freed.
See Memory Leaks. WARNING: This should be used with caution
since you may run out of heap space.
allow-free-null
The library will not generate an error when a program tries to free a
NULL pointer. See ALLOW_FREE_NULL and ALLOW_FREE_NULL_MESSAGE settings
in the settings.h file which change the default behavior.
NOTE: This does not impact the ALLOW_REALLOC_NULL compilation
options which can be adjusted in conf.h.
error-dump
Dump core on error and then continue. Later core dumps overwrite
earlier ones if the program encounters more than one error. See
error-abort above.
NOTE: This will only work if your system supports the fork
system call and the configuration utility was able to fork without going
recursive.
By using a RC File (or runtime configuration file) you can alias
tags to combinations of debug tokens. See Debug Tokens.
NOTE: For beginning users, the dmalloc program has a couple of
tags built into it so it is not necessary for you to setup a RC file:
runtime
enables basic runtime tests
low
turns on minimal checking of heap structures
medium
significant checking of heap areas
high
extensive checking of heap areas
all
turns on all the checking possible. This generates a multitude of log
messages without many more tests than high.
For expert users, a sample dmallocrc file has been provided but
you are encouraged to roll your own combinations. The name of default
rc-file is $HOME/.dmallocrc. The $HOME environment
variable should be set by the system to point to your home-directory.
The file should contain lines in the general form of:
tag token1, token2, ...
tag is to be matched with the tag argument passed to the dmalloc
program, while token1, token2, ... are debug capability
tokens. See Dmalloc Program, 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.
Here is an example of a .dmallocrc file:
#
# Dmalloc runtime configuration file for the debug malloc library
#
# no debugging
none none
# basic debugging
debug1 log-stats, log-non-free, check-fence
# more logging and some heap checking
debug2 log-stats, log-non-free, log-trans, \
check-fence, check-heap, check-lists, error-abort
# good utilities
debug3 log-stats, log-non-free, log-trans, \
log-admin, check-fence, check-heap, check-lists, realloc-copy, \
free-blank, error-abort
...
For example, with the above file installed, you can type dmalloc
debug1 after setting up your shell alias. See Dmalloc Program.
This enables the logging of statistics, the logging of non-freed memory,
and the checking of fence-post memory areas.
Enter dmalloc none to disable all memory debugging features.
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
For more information about administration structures, see the code and
comments from chunk_loc.h.
Realloc() backwards compatibility with being able to realloc from the
last freed block is not supported. The author is interested to
know who is using this (cough, cough) feature and for what reason.
Realloc() of a NULL pointer is supported in which case the library will
just make a call to malloc(). This can be disabled with the help of a
manual compilation option in the conf.h file.
Some systems allow free(0) to not be an error for some reason. Since 0
is not a valid address returned by the malloc call, it is debatable that
this should be allowed. See conf.h for some manual compilation
options to handle this.
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.
Whether the systems' 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.
The library has not been tested on a system whose heap grows towards low
memory. If you are trying to run the library on such a system please
contact the author.
The locating of the caller's address from the dmalloc functions.
This is useful in locating problems from dmalloc functions called from C
files which did not include dmalloc.h: C library calls for
instance.
See return.h for the available architecture/compiler
combinations. You may want to examine the assembly code from gcc (GNUs
superior c-compiler) version 2+ being run on the following code. It
should give you a good start on building a hack for your box.