How to Use the malloc_history Command in macOS Terminal to Trace Memory Allocation Call Stacks

Diagnosing memory leaks or unexpected heap growth in macOS applications often leaves developers with a frustrating mystery: tools like vmmap and heap can tell you that an object exists at hex address 0x6000028a4120, but they cannot tell you who allocated it, which function created it, or what the execution call stack looked like at the precise moment of allocation.

To provide this missing forensic detail, macOS includes a specialized command-line profiling tool: malloc_history. Located in /usr/bin/malloc_history, this utility inspects recorded allocation event logs to print the complete C, Objective-C, and Swift backtraces for any valid heap pointer. This guide explains how to enable allocation logging, execute malloc_history, and trace memory leaks to their exact line of source code.

How malloc_history Works

Under normal execution, macOS discards function call stacks as soon as malloc() completes to maximize performance. To allow malloc_history to inspect allocation events, the target application must be launched with the system’s allocation logger enabled via environment variables:

  • MallocStackLogging: Instructs the libmalloc allocator to record complete stack backtraces for all live memory allocations.
  • MallocStackLoggingNoCompact: Preserves historical records of both active allocations and previously freed memory addresses, allowing you to debug use-after-free and double-free crashes.

Launching an Application with MallocStackLogging Enabled

To inspect an application’s allocation history, launch it from the macOS Terminal with the required environment flag:

# Launch app with live allocation logging
export MallocStackLogging=1
/Applications/YourApp.app/Contents/MacOS/YourApp &

Note the Process ID (PID) displayed in the terminal upon launch.

Tracing Object Allocations with malloc_history

1. Locate the Leaking Object Address

Use the companion heap or leaks command to find the memory address of an unexpected object:

sudo heap -addresses "CustomDataModel" 14205

Suppose this command outputs the memory address 0x6000018fa080.

2. Inspect the Allocation Backtrace

Pass the PID and hex address to malloc_history:

sudo malloc_history 14205 0x6000018fa080

The command outputs the chronological call stack that originally spawned that object:

ALLOC 0x6000018fa080-0x6000018fa0bf [size=64]: thread_1204
  0 libsystem_malloc.dylib  malloc_zone_malloc
  1 libsystem_malloc.dylib  malloc
  2 libswiftCore.dylib       swift_allocObject
  3 YourApp                 SpecialReport.init(data:) (SpecialReport.swift:42)
  4 YourApp                 ReportManager.generateReport() (ReportManager.swift:118)
  5 YourApp                 closure #1 in DashboardViewController.viewDidLoad() (DashboardViewController.swift:56)
  6 AppKit                  -[NSViewController _sendViewDidLoad]
  7 AppKit                  -[NSViewController loadView]

In this output, line 3 immediately pinpoints the exact file and line number (SpecialReport.swift:42) that allocated the unreleased object.

Inspecting All Allocations by Size

You can also use malloc_history to audit all allocations matching a specific byte size or function signature:

# Print call stacks for all 4096-byte page allocations
sudo malloc_history 14205 -callTrees -size 4096

Comparing macOS Memory Investigation Utilities

Command Primary Diagnostic Role Prerequisites
vmmap Virtual memory regions and physical dirty pages None (Standard execution)
heap Class instance counts and cumulative zone sizes None (Standard execution)
leaks Detects unreferenced orphaned heap nodes None (Works best with symbols)
malloc_history Prints allocation call stack backtraces Must launch with MallocStackLogging=1

Best Practices and Performance Considerations

  • Development Environments Only: MallocStackLogging introduces approximately 10–25% memory overhead and disk I/O to store stack logs. Never leave it permanently enabled on production corporate systems.
  • Clearing Log Caches: Temporary stack logs are automatically cleared from /tmp when the target application process terminates.

Get the best tech tips delivered straight to your inbox.

Join thousands of readers mastering Apple, Google, Microsoft, and Linux.