Unknown option: "-3"
Unix manual page for libgmalloc. (host=minya system=Darwin)
libgmalloc(3) BSD Library Functions Manual libgmalloc(3)
NAME
libgmalloc -- (Guard Malloc), an aggressive debugging malloc library
DESCRIPTION
libgmalloc is a debugging malloc library that can track down insidious
bugs in your code or library. If your application crashes when using
libgmalloc, then you've found a bug.
libgmalloc is used in place of the standard system malloc, and uses the
virtual memory system to identify memory access bugs. Each malloc allo-
cation is placed on its own virtual memory page (or pages). By default,
the returned address for the allocation is positioned such that the end
of the allocated buffer is at the end of the last page, and the next page
after that is kept unallocated. Thus, accesses beyond the end of the
buffer cause a bad access error immediately. When memory is freed, libg-
malloc deallocates its virtual memory, so reads or writes to the freed
buffer cause a bad access error. Bugs which had been difficult to iso-
late become immediately obvious, and you'll know exactly which code is
causing the problem.
Guard Malloc is thread-safe and works for all uses of malloc(), Objec-
tive-C's alloc method, C++'s new operator, and other functions which
result in allocation in the malloc heap.
As of Mac OS X 10.11, Guard Malloc works with purgeable memory. Alloca-
tions of *any* size that are allocated through malloc_zone_malloc(mal-
loc_default_purgeable_zone(), <size>) are handled as purgeable memory.
When malloc_make_purgeable() is called for a purgeable allocation, the
memory is immediately purged. Attempting to access that memory will then
cause a crash. To access that memory successfully, first call mal-
loc_make_nonpurgeable() then recreate the data.
As of Mac OS X 10.5, libgmalloc aligns the start of allocated buffers on
16-byte boundaries by default, to allow proper use of vector instructions
(e.g., SSE). (The use of vector instructions is common, including in
some Mac OS X system libraries. The regular system malloc also uses
16-byte alignment.) Because of this 16-byte alignment, up to 15 bytes at
the end of an allocated block may be excess at the end of the page, and
libgmalloc will not detect buffer overruns into that area by default.
This default alignment can be changed with environment variables.
libgmalloc is available in /usr/lib/libgmalloc.dylib. To use it, set
this environment variable:
set DYLD_INSERT_LIBRARIES to /usr/lib/libgmalloc.dylib
Note: it is no longer necessary to set DYLD_FORCE_FLAT_NAMESPACE.
This tells dyld to use Guard Malloc instead of the standard version of
malloc. Run the program, and wait for the crash indicating the bad
access. When the program crashes, examine it in the debugger to identify
the cause.
As of Mac OS X 10.6, libgmalloc can be used with the standard malloc
stack logging by setting the MallocStackLogging environment variable.
The malloc_history(1) command can then be used to show backtraces of all
malloc and free events made when using libgmalloc.
USING libgmalloc WITH THE XCODE DEBUGGER OR LLDB
Because the goal of libgmalloc is to "encourage" your application to
crash if memory access errors occur, it is best to run your application
under a debugger such as the Xcode IDE's debugger, or lldb at the command
line.
To use Guard Malloc with the Xcode debugger, choose Edit Scheme... from
the Scheme popup. Click on the Diagnostics tab then turn on the Enable
Guard Malloc check box. Then when launching the target application,
Xcode automatically sets the DYLD_INSERT_LIBRARIES environment variable
properly. Xcode retains that setting with that executable. To set any
of the additional environment variables described below, click on the
Arguments tab in the Scheme editor and add them in the Environment Vari-
ables section.
If you're using lldb from the command line, use lldb's "settings set tar-
get.env-vars VAR=VALUE" command to set the environment variables. Or
simply use the "env VAR=VALUE" command alias.
EXAMPLE
% cat gmalloctest.c
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char **argv) {
unsigned *buffer = (unsigned *)malloc(sizeof(unsigned) * 100);
unsigned i;
for (i = 0; i < 200; i++) {
buffer[i] = i;
}
for (i = 0; i < 200; i++) {
printf ("%d ", buffer[i]);
}
}
% cc -g -o gmalloctest gmalloctest.c
% lldb gmalloctest
Current executable set to 'gmalloctest' (x86_64).
(lldb) env DYLD_INSERT_LIBRARIES=/usr/lib/libgmalloc.dylib
(lldb) process launch
Process 7895 launched: '/private/tmp/testit/gmalloctest' (x86_64)
GuardMalloc[gmalloctest-7895]: Allocations will be placed on 16 byte boundaries.
GuardMalloc[gmalloctest-7895]: - Some buffer overruns may not be noticed.
GuardMalloc[gmalloctest-7895]: - Applications using vector instructions (e.g., SSE) should work.
GuardMalloc[gmalloctest-7895]: version 105
Process 7895 stopped
* thread #1: tid = 0x6880e, 0x0000000100000eda gmalloctest`main(argc=1, argv=0x00007fff5fbffa00) + 74 at gmalloctest.c:9, stop reason = EXC_BAD_ACCESS (code=1, address=0x100342000)
frame #0: 0x0000000100000eda gmalloctest`main(argc=1, argv=0x00007fff5fbffa00) + 74 at gmalloctest.c:9
6 unsigned i;
7
8 for (i = 0; i < 200; i++) {
-> 9 buffer[i] = i;
10 }
11
12 for (i = 0; i < 200; i++) {
(lldb) print i
(unsigned int) $0 = 100
(lldb) print &buffer[i]
(unsigned int *) $1 = 0x0000000100342000
Once you have the backtrace, you can examine that line of source code to
see what variable was accessed, and determine why that address was
invalid memory. In the example above, notice that it crashes when it
tries to write one character beyond the end of the malloc'ed buffer it's
operating on, causing a bad access error when accessing the protected
page following the string.
These sorts of problems may seem minor, especially when the application
normally behaves correctly. However, they're usually the hallmark of
intermittent bugs or unexplained crashes in long running programs. In
normal use, the bug in the example program might have caused no problems
at all... or it might have trashed the following buffer, leading occa-
sionally to corrupted data. If the application had been referencing
freed memory, the program might have worked fine until the one time where
the freed memory was immediately reused and modified.
ENVIRONMENT
libgmalloc's behavior can be changed with several additional environment
variables:
MALLOC_LOG_FILE <f> Create or append messages to the given
file path <f> instead of writing to the
standard error. This can be set to
/dev/null to completely suppress all out-
put if necessary.
MALLOC_PROTECT_BEFORE If this flag is set, then libgmalloc tries
harder to detect buffer underruns.
Specifically, libgmalloc places the start
of the allocated buffer at the beginning
of a virtual memory page, then protects
the page before. Buffer underruns then
cause an error. The behavior without this
variable set is to place the end of the
buffer at the end of the last page of the
allocation, and protect the page after.
MALLOC_FILL_SPACE This flag causes libgmalloc to fill the
buffer with 0x55 upon creation. This can
help catch uninitialized memory problems.
MALLOC_ALLOW_READS This flag allows the guard page after the
buffer to be readable so that reads past
the ends of buffers do not cause the pro-
gram to crash. With the MALLOC_PRO-
TECT_BEFORE flag set, this command instead
sets the guard page before the buffer to
be readable.
MALLOC_VECTOR_SIZE This option is the default alignment, as
of Mac OS X 10.5. With this option, Guard
Malloc places allocations on 16 byte
boundaries, because vector instructions
(e.g., SSE) require buffers to be on 16
byte boundaries. (The use of vector
instructions is becoming more common in
some Mac OS X system libraries.)
MALLOC_WORD_SIZE This flag specifies that Guard Malloc
should place allocations on word (4-byte)
boundaries, with the end of the buffer on
the last 4 bytes of the page. This option
is useful because Carbon assumes that
pointers are word aligned, and without the
word alignment, any program relying on
Cocoa or Carbon would immediately crash.
MALLOC_STRICT_SIZE This flag specifies that Guard Malloc
should always align all allocations on
single-byte boundaries such that the last
byte of the buffer is at the end of the
page. This will immediately catch even
one-byte buffer overruns, but applications
that use Carbon or Cocoa, or vector
instructions, may not run properly with
this option.
MALLOC_PERMIT_INSANE_REQUESTS GuardMalloc tries to protect against
requests for insane amounts of memory by
instructing the program to trap (if run-
ning under the debugger) if more than
100MB is requested. If this environment
variable is set, then the check is dis-
abled.
MALLOC_MAXIMUM_VM To test how a process handles running out
of memory, set this variable to the maxi-
mum size, in bytes, of the allocations for
the process (including the extra overhead
from rounding allocations up to a full
page size). When this limit is hit,
attempts to allocate additional memory
return NULL. If MALLOC_PER-
MIT_INSANE_REQUESTS is not set it will
also trap (if running under the debugger).
MALLOC_CHECK_HEADER This flag is enabled by default, which
causes Guard Malloc to check the validity
of a magic number in the malloc block
header when a block is freed or reallo-
cated. To turn off this checking, set
this environment variable to NO or 0.
MallocStackLogging If this flag is set, then standard system
malloc stack logging is enabled. The
malloc_history(1) command can then be used
to show backtraces of all malloc and free
events made when using libgmalloc.
MEMORY VALUES USED BY GUARD MALLOC
It's often useful to understand how Guard Malloc uses memory when debug-
ging. Guard Malloc writes strange byte sequences to catch certain prob-
lems. If the MALLOC_FILL_SPACE environment variable is set, newly allo-
cated buffers will be filled with the value 0x55 in hopes of catching
references to uninitialized memory.
The space right before the buffer is dedicated to header information. If
MALLOC_PROTECT_BEFORE was set, the header immediately follows the buffer.
The header is 16 bytes in 32-bit processes and 32 bytes in 64-bit pro-
cesses and is organized as:
magic number (0xdeadbeef in 32-bit, or 0xdeadbeefdeadbeef in 64-bit)
size of buffer + size of header
thread id
magic number again
CAVEATS
Because each allocation requires at least two pages of virtual memory, in
32-bit processes only about 500,000 malloc allocations could exist before
the process runs out of virtual memory.
Processes using Guard Malloc may run more slowly. In addition, the extra
pressure on the virtual memory system when running a process with Guard
Malloc can cause top(1) to update its output more slowly.
Don't forget -- if there's a memory bug in your program, the program will
crash in Guard Malloc. This is a feature!
SEE ALSO
malloc_history(1)
Mac OS X Mar. 18, 2015 Mac OS X