memtool(1)
memtool --
diagnose dynamic memory allocation errors
Synopsis
memtool
[-flnqsvwxz] [-a argno]
[-d depth] [-i ignsigs]
[-o file]
command [command_arguments ...]
Description
memtool helps you find and diagnose
dynamic memory allocation bugs in your program.
You start your application just as usual,
except that you run it through memtool.
For example:
$ memtool your_prog its_args
memtool analyzes and reports detailed information
about the following misuses of allocated memory:
-
writing past the end of a block (or before it)
-
using deallocated blocks
-
``leaked'' blocks
-
bad arguments to passed to the
malloc(3C)
or
new(3C++std)
routines
In this context,
``blocks'' are the individual objects
that comprise the allocation ``arena''
-- the objects whose addresses are returned by
malloc(3C)
or
new(3C++std).
Options
Options to memtool adjust its behavior
to help you diagnose specific problems:
-a argno-
cause memtool to store
argno ``words'' (3 by default)
for each function in each stack trace.
-d depth-
cause memtool to limit the stack traces
to depth functions.
By default, complete stack traces are saved.
-f-
cause memtool to track
the child processes of your application.
By default, memtool only manages the initial process.
-i ignsigs-
cause memtool to ignore the delivery
of the specified signal numbers.
ignsigs is a list of signals
separated by a space or comma.
memtool emits information
about the state of your application
when it detects the delivery of any unignored signals.
See the -s option as well.
-l-
cause memtool to not list ``leaked'' blocks.
These are the blocks still available
for your application to use as your application exits.
-n-
cause memtool to make
null pointer references generate segmentation faults.
-o <file>-
cause memtool to write its diagnostic information
to file instead of the standard error output.
-q-
cause memtool to emit briefer diagnostic messages.
-s-
cause memtool to not display information
regarding the delivery of signals to your application.
See the -i option as well.
-v-
cause memtool to emit longer messages.
In particular, you get a very long introductory message
before the first detected misuse with this option.
If combined with -q,
the -v option has no effect.
-w-
cause memtool to perform complete walks
through the allocation arena for each call to the
malloc(3C)
routines.
This can cause a noticeable slow-down in your application.
-x-
cause memtool to change every allocation
so a few extra bytes are allowed at the end of the block.
This can be useful in changing when and where
an inappropriate block modification takes place
and when it is detected.
If -x is not specified,
memtool does not change the block sizes and addresses
used in your application.
-z-
cause memtool to warn when zero (or null) arguments
are passed to the
malloc( )
routines.
By default, these are silently accepted, as normal.
Usage
memtool provides the best information
when the application has been built with debugging information;
see the -g option to
cc(1)
or
CC(1C++).
It is not, however, necessary to build your program
in any special way to use memtool;
all that is required is that it use
the dynamic C library
malloc(3C)
directly or indirectly
(such as through the C++
new(3C++std)
routines) and can be processed by
debug(1).
memtool can only detect
dynamic memory misuses as provided by
the checking features documented in
malloc(3C).
For example, it cannot detect general pointer misuses,
the overrunning of local or global arrays,
or distinguish between
intended and unintended use of a block.
Each diagnostic includes one to three stack traces:
-
when the misuse was detected
-
when the associated block was (de)allocated
-
block's previous stack trace for
realloc( ),
free( ),
or operator delete.
If the misuse is an inappropriately modified block,
an annotated memory snapshot of the block is also provided,
highlighting where the block was found to have been modified.
Notices
memtool is written to have minimal impact
on the execution of the program being analyzed.
Unless you use the -x option,
all addresses returned for the
malloc(3C)
routines are unchanged,
although most stack addresses are modified.
The application is also being run under the control of
debug(1),
which is particularly noteworthy for applications
that are timing-sensitive,
such as those that use threads.
memcopy can consume large chunks of
mmap(2)
virtual space for the internal sanity checking in the
malloc(3C)
routines.
Applications usually run slower under memtool,
especially when the -w option is used.
Examples
Given the following contrived C source code
$ cat bad.c
#include <stdlib.h>
static void *f(void *p) {
free(p);
return malloc(0);
}
int main(void) {
char *p = malloc(13);
p[13] = 'x';
f(p);
p = realloc(p, 7);
return 0;
}
Building it and running it, we see nothing wrong:
$ cc -g -o bad bad.c
$ ./bad
$ echo $?
0
But, if run with memtool:
$ memtool ./bad
we get nearly a hundred lines of diagnostics,
including the following.
Note that bad.c was compiled with the -g option
to generate debugging information,
so the memtool output
is more detailed than it would otherwise be.
A block's spare bytes have been modified. This usually occurs due to
writing beyond the block's regular bytes, either because an insufficient
number of bytes were requested when the block was allocated or simply
due to a programming logic error.
History for block at address 0x80496f8:
*Stack trace when detected:
[0] free(ptr=0x80496f8)
[1] f(p=0x80496f8) [bad.c@3] in ./bad
[2] main(0x1,0x8047a34,0x8047a3c) [bad.c@9] in ./bad
[3] _start() [0x804856c] in ./bad
*Stack trace when block at 0x80496f8 was allocated:
[0] malloc(sz=13)
[1] main() [bad.c@7] in ./bad
[2] _start(presumed:0x1,0x8047a34,0x8047a3c) [0x8048571] in ./bad
Annotated snapshot surrounding the live allocation at address 0x80496f8
when the byte at 0x8049705 was found to have been modified. This
allocation holds 13 bytes followed by 7 extra (or spare) bytes,
and, in this case, a spare byte was found to have been modified.
0x80496f0: 0x08047a34 0x00000019 0xcacacaca 0xcacacaca 4z..............
: ******** -------- -------- ****--------
0x8049700: 0xcacacaca 0xcaca78ca 0xcacacaca 0x0000001d .....x..........
: -------- ++++^^-- ++++++++ -----^++++++
as well as a complaint about the misuse of realloc():
A recently free()d block was passed as the first argument to realloc().
Only null pointers or live block addresses are permitted to be passed to
realloc(), although, in this implementation, were dynamic memory checking
not enabled, this block's contents would have been preserved between its
being freed and this call to realloc(), but this is a nonportable feature
of this implementation which should not be relied on.
History for block at address 0x80496f8:
*Stack trace when detected:
[0] realloc(ptr=0x80496f8,sz=7)
[1] main(0x1,0x8047a34,0x8047a3c) [bad.c@10] in ./bad
[2] _start() [0x804856c] in ./bad
*Stack trace when block at 0x80496f8 was released:
[0] free(ptr=0x80496f8)
[1] f(p=0x80496f8) [bad.c@3] in ./bad
[2] main() [bad.c@9] in ./bad
[3] _start(presumed:0x1,0x8047a34,0x8047a3c) [0x8048571] in ./bad
*Stack trace when block at 0x80496f8 was allocated:
[0] malloc(sz=13)
[1] main() [bad.c@7] in ./bad
[2] _start(presumed:0x1,0x8047a34,0x8047a3c) [0x8048571] in ./bad
There were also complaints about two leaked blocks.
If the -z option were used,
memtool would also generate a warning
about the malloc(0)
on line 4.
Because bad.c was compiled with the -g option
to generate debugging information,
the memtool output includes the source file and line number
in the stack trace lines
as well as the parameter names.
Had the code been compiled without -g,
each function would show three hexadecimal arguments.
memtool can be run on a stripped program,
but the output will not show even the function names.
References
cc(1),
CC(1C++),
debug(1),
truss(1)
malloc(3C),
new(3C++std)
© 2004 The SCO Group, Inc. All rights reserved.
UnixWare 7 Release 7.1.4 - 25 April 2004