Mac Developer Library Developer
Search

 

This manual page is for Mac OS X version 10.9

If you are running a different version of Mac OS X, view the documentation locally:

  • In Terminal, using the man(1) command

Reading manual pages

Manual pages are intended as a quick reference for people who already understand a technology.

  • To learn how the manual is organized or to learn about command syntax, read the manual page for manpages(5).

  • For more information about this technology, look for other documentation in the Apple Developer Library.

  • For general information about writing shell scripts, read Shell Scripting Primer.




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 iden-tify identify
     tify memory access bugs.  Each malloc allocation 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,
     libgmalloc deallocates its virtual memory, so reads or writes to the freed buffer cause a bad access
     error.  Bugs which had been difficult to isolate 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(), Objective-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.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 Mal-locStackLogging MallocStackLogging
     locStackLogging environment variable.  The malloc_history(1) command can then be used to show back-traces backtraces
     traces 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 appli-cation, application,
     cation, 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 Variables
     ables section.

     If you're using lldb from the command line, use lldb's "settings set target.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 27
     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 pro-
     grams.  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 occasionally 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 sup-press suppress
                                    press all output 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 program to crash.  With
                                    the MALLOC_PROTECT_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 bound-aries. boundaries.
                                    aries.  (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 alloca-tions allocations
                                    tions 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 mem-ory memory
                                    ory by instructing the program to trap (if running under the debugger)
                                    if more than 100MB is requested.  If this environment variable is set,
                                    then the check is disabled.

     MALLOC_MAXIMUM_VM              To test how a process handles running out of memory, set this variable
                                    to the maximum 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_PERMIT_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 reallocated.  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 back-traces backtraces
                                    traces 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 debugging.  Guard Malloc writes
     strange byte sequences to catch certain problems.  If the MALLOC_FILL_SPACE environment variable is
     set, newly allocated 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 processes 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
     libgmalloc doesn't come without some weaknesses.  First, because each allocation requires at least two
     pages of virtual memory, in 32-bit processes only about 500,000 malloc allocations could conceivably
     exist before the process runs out of virtual memory.  The extravagant use of virtual memory will also
     cause much more swapping, so the program will run much slower than usual -- usually two orders of mag-nitude magnitude
     nitude (100x).

     In addition, the extra pressure on the virtual memory system when running an application 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. 12, 2013                        Mac OS X

Reporting Problems

The way to report a problem with this manual page depends on the type of problem:

Content errors
Report errors in the content of this documentation with the feedback links below.
Bug reports
Report bugs in the functionality of the described tool or API through Bug Reporter.
Formatting problems
Report formatting mistakes in the online version of these pages with the feedback links below.

Feedback