NAME
malloc_history
—
Show the malloc and anonymous VM
allocations that the process has performed
SYNOPSIS
malloc_history |
process [-highWaterMark ]
address [address ...] |
malloc_history |
process -allBySize
[-highWaterMark ] [address
...] |
malloc_history |
process -allByCount
[-highWaterMark ] [address
...] |
malloc_history |
process -allEvents
[-highWaterMark ]
[-showContent ] |
malloc_history |
process -callTree
[-highWaterMark ]
[-showContent ] [-invert ]
[-ignoreThreads ]
[-collapseRecursion ]
[-chargeSystemLibraries ]
[-virtual ] [address ... |
<classes-pattern>]
process is a pid, executable-name, or memory-graph-file |
DESCRIPTION
malloc_history
inspects a given process
and lists the malloc and anonymous VM allocations performed by it. Anonymous
VM allocations are from calls such as mach_vm_allocate that allocate raw
Virtual Memory that is not backed by a file. Allocations of the VM regions
underlying the malloc heaps are ignored.
malloc_history
relies on information provided by the
standard malloc library when malloc stack logging has been enabled for the
target process. See below for further information.
The target process may be specified by pid or by full or partial
name, or it can be the path of a memory graph file generated by
leaks
or the Xcode Memory Graph Debugger.
If the -highWaterMark
option is passed,
malloc_history
first scans through the all malloc
stack log records to calculate the "high water mark" of allocated
memory -- i.e., the highest amount of allocated memory used at any one time
by the target process. It then shows information about the malloc
allocations and anonymous VM regions that were live at that time, rather
than currently alive in the target program.
The -highWaterMark
option does not work
with memory graph files since they only contain stack logs for active
allocations, not full history.
By specifying one or more addresses,
malloc_history
lists all allocations and
deallocations of any malloc blocks or VM regions that started at or
contained those addresses. For each allocation, a stack trace describing who
called malloc or free, or mach_vm_allocate, mmap, or mach_vm_deallocate is
listed. If you do only wish to see events for malloc blocks and VM regions
that started at the specified address, you can grep the output for that
address. If -highWaterMark
is passed, it only shows
allocations and deallocations up to the high water mark.
Alternatively, the -allBySize
and
-allByCount
options list all allocations that are
currently live in the target process, or were live at the high water mark.
Frequent allocations from the same point in the program (that is, the same
call stack) are grouped together, and output presented either from largest
allocations to smallest, or most allocations to least. If you also specify
one or more addresses, this output is filtered to only show information for
malloc blocks containing those addresses.
The -allEvents
option lists all allocation
and free events, for all addresses, up to the current time or to the high
water mark. This output can be voluminous. If the
-showContent
option is passed, live allocations will
have additional details as described for that option below.
The -callTree
option generates a call tree
of the backtraces of malloc calls and anonymous VM regions for live
allocations in the target process, or for allocations that were live at the
high water mark. The call tree can be filtered to backtraces of specific
allocations or classes, by passing one or more addresses or a
<classes-pattern>.
The <classes-pattern> regular expression is interpreted as an extended (modern) regular expression as described by the re_format(7) manual page. "malloc" or "non-object" can be used to refer to blocks that are not of any specific type. Examples of valid classes-patterns include:
- CFString
- 'NS.*'
- '__NSCFString|__NSCFArray'
- '.*(String|Array)'
- 'VM:.*'
- malloc
- non-object
- malloc|.*String
The <classes-pattern> pattern can be followed by an optional allocation size specifier, which can be one of the following forms. The square brackets are required. The size can include a 'k' suffix for kilobytes, or an 'm' suffix for megabytes:
- [size]
- [lowerBound-upperBound]
- [lowerBound+]
- [-upperBound]
Examples of <classes-pattern> with size specifications include:
- malloc[2048]
- all malloc blocks of size 2048
- malloc[1k-8k]
- all malloc blocks between 1k and 8k
- '(NS|CF).*[10k+]'
- all NS or CF objects 10k or larger
- [-1024]
- all allocations 1024 bytes or less
- VM.*[1m+]
- all Virtual Memory regions of size 1m or larger; by default this is dirty+swapped-volative size, unless the -virtual flag is passed
The call tree format is similar to the output from
sample(1).
The resulting call tree can be filtered or pruned with the
filtercalltree(1) tool for further analysis. Additional options for
the -callTree
mode include:
-showContent
- Show the content of malloc blocks of various types, including C strings, Pascal strings (with a length byte at the start), and various objects including NSString, NSDate, and NSNumber.
-invert
- Invert the call tree, so that malloc (and the allocated content, if the
-showContent
option was given) show at the top of the call trees. -ignoreThreads
- Combine the call trees for all threads into a single call tree.
-collapseRecursion
- Collapse recursion within the call trees.
-chargeSystemLibraries
- Remove stack frames from all libraries in /System and /usr, while still charging their cost (number of calls, allocation size, and content) to the callers.
-virtual
- Display the size of VM regions as the virtual size, rather than the default dirty + swapped/compressed - purgableVolatile.
All modes require the standard malloc library's debugging facility to be turned on. To do this, set either the MallocStackLogging or MallocStackLoggingNoCompact environment variable to 1 in the shell that will run the program. If MallocStackLogging is used, then when recording events, if an allocation event for an address is immediately followed by a free event for the same address, both events are removed from the event log. If MallocStackLoggingNoCompact is used, then all such immediate allocation/free pairs are kept in the event log, which can be useful when examining all events for a specific address, or when using the -allEvents option.
If both MallocStackLogging and MallocStackLoggingNoCompact are set, then MallocStackLogging takes precedence and MallocStackLoggingNoCompact is ignored.
malloc_history
is particularly useful for
tracking down memory smashers. Run the program to be inspected with
MallocStackLogging or MallocStackLoggingNoCompact defined. Also set the
environment variable MallocScribble; this causes the malloc library to
overwrite freed memory with a well-known value (0x55), and occasionally
checks freed malloc blocks to make sure the memory has not been overwritten
since it was cleared. When malloc detects the memory has been written, it
will print out a warning that the buffer was modified after being freed. You
can then use malloc_history
to find who allocated
and freed memory at that address, and thus deduce what parts of the code
might still have a pointer to the freed structure.
EXAMPLE
To see backtraces of allocations by class type or malloc size, run this command:
% malloc_history <process> -callTree -invert -showContent
SEE ALSO
malloc(3), heap(1), leaks(1), stringdups(1), vmmap(1), filtercalltree(1), DevToolsSecurity(1)
The Xcode developer tools also include Instruments, a graphical
application that can give information similar to that provided by
malloc_history.
The Allocations instrument
graphically displays dynamic, real-time information about the object and
memory use in an application, including backtraces of where the allocations
occured.