Back to Blog

How to Check Loaded Modules and Libraries of a Process on macOS

Learn how to inspect dynamic libraries (dylibs) and frameworks loaded by a running process on macOS using vmmap, otool, lsof, dyld_info, and ProcXray.

Every macOS application loads dynamic libraries (dylibs) and frameworks at runtime. Inspecting these loaded modules helps you debug linking issues, audit third-party dependencies, detect injected libraries, and understand an app’s internal architecture. This guide covers five methods to check what modules a process has loaded — from built-in command-line tools to a dedicated GUI app.

Quick Answer

Use vmmap <pid> | grep '\.dylib' in Terminal to list all dynamic libraries loaded by a running process. For static link dependencies, use otool -L /path/to/binary. For a visual, searchable interface that shows loaded modules with file paths, versions, and UUIDs in one click, use ProcXray.

What Are Loaded Modules on macOS?

A loaded module is a dynamic library (.dylib), framework (.framework), or bundle (.bundle) that the macOS dynamic linker (dyld) maps into a process’s address space at runtime. There are two categories:

macOS system processes typically load 100–300 modules, while complex apps like Xcode or Chrome can load over 1,000. Knowing which modules are loaded is critical for diagnosing crashes, identifying version conflicts, and auditing security.

Method 1: vmmap — List All Loaded Modules of a Running Process

The vmmap command displays the virtual memory regions of a running process. Since each loaded dylib occupies its own memory region, you can filter the output to see every module currently in memory.

# List all loaded dylibs for a running process by PID
vmmap <pid> | grep '\.dylib'

To find the PID first:

# Find the PID of Safari
pgrep -x Safari

Example output:

__TEXT   7FF80B2A0000-7FF80B2C1000  r-x/r-x  /usr/lib/system/libsystem_kernel.dylib
__TEXT   7FF80B2C1000-7FF80B2FD000  r-x/r-x  /usr/lib/system/libsystem_c.dylib
__TEXT   7FF80B300000-7FF80B365000  r-x/r-x  /usr/lib/libobjc.A.dylib

Each line shows the memory address range, permissions, and the full path to the loaded library.

To include frameworks as well:

# Show all loaded dylibs and frameworks
vmmap <pid> | grep -E '\.(dylib|framework)/'

To count how many modules are loaded:

vmmap <pid> | grep '\.dylib' | awk '{print $NF}' | sort -u | wc -l

When to use vmmap

Use vmmap when you need to see everything a running process has actually loaded into memory, including runtime-loaded modules that otool cannot show. It requires the process to be running and may require elevated privileges for system processes.

The otool command inspects Mach-O binaries. The -L flag lists all dynamic libraries the binary is linked against at compile time.

# List linked libraries for an application binary
otool -L /Applications/Safari.app/Contents/MacOS/Safari

Example output:

/Applications/Safari.app/Contents/MacOS/Safari:
    /System/Library/Frameworks/WebKit.framework/Versions/A/WebKit
    /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit
    /usr/lib/libSystem.B.dylib
    /usr/lib/libc++.1.dylib

This shows the libraries the binary expects to load — its compile-time dependencies. It does not show libraries loaded at runtime via dlopen().

To inspect a specific dylib’s own dependencies:

otool -L /usr/lib/libobjc.A.dylib

When to use otool

Use otool -L when you want to know what a binary should load before even running it. This is useful for verifying build configurations, checking that the correct SDK frameworks are linked, and detecting missing dependencies.

Method 3: lsof — Find Loaded Libraries via Open Files

The lsof command lists all files opened by a process. Since loaded libraries are memory-mapped files, they appear in lsof output.

# List all loaded .dylib files for a process
lsof -p <pid> | grep '\.dylib'

To include frameworks:

lsof -p <pid> | grep -E '\.(dylib|framework)'

When to use lsof

Use lsof when you need a quick check and are already familiar with it. However, vmmap provides more detailed information (memory addresses, permissions) and is the preferred tool for module inspection.

Method 4: dyld_info — Inspect the Dynamic Linker

Starting from macOS 12 (Monterey), Apple provides the dyld_info command for inspecting dynamic linker information.

# Show all dependent dylibs of a binary
dyld_info -dependents /Applications/Safari.app/Contents/MacOS/Safari

For inspecting a running process’s dyld shared cache usage:

# List platform and dependencies
dyld_info -platform -dependents /usr/lib/libobjc.A.dylib

When to use dyld_info

Use dyld_info when you need detailed information about dynamic linker behavior, including platform requirements and dependency chains. It provides cleaner output than otool for dependency analysis.

Method 5: ProcXray — Visual Module Inspector

ProcXray provides a dedicated Modules tab that displays every loaded module for any running process — no commands to remember, no output to parse.

How to inspect modules with ProcXray

  1. Launch ProcXray.
  2. Select a process from the process list (use the search bar or tree view to find it).
  3. Click the Modules tab in the detail panel.
  4. Browse the full list of loaded dylibs and frameworks, with file paths and details.

Use the search field in the Modules tab to filter by library name — for example, type “libsystem” to find all loaded system libraries, or “swift” to locate Swift runtime modules.

ProcXray Modules tab showing loaded libraries for a process with search filtering

What ProcXray adds over CLI tools

Comparison of Methods

Featurevmmapotool -Llsofdyld_infoProcXray
Shows runtime-loaded modulesYesNoYesNoYes
Shows static dependenciesNoYesNoYesNo
Requires process to be runningYesNoYesNoYes
Memory address detailsYesNoNoNoNo
Search / filterManual (grep)Manual (grep)Manual (grep)NoBuilt-in
Ease of useModerateEasyModerateEasyEasiest
macOS versionAllAllAll12+14+

Practical Use Cases

# Check if the expected library version is loaded
vmmap <pid> | grep 'libssl'

If the output points to a different libssl than expected (for example, a Homebrew version instead of the system one), you have found the version conflict.

Auditing an app for injected libraries

Security researchers and developers can check if unexpected libraries have been loaded into a process:

# Look for libraries not from /System or /usr/lib
vmmap <pid> | grep '\.dylib' | grep -v '/System/' | grep -v '/usr/lib/'

Any results may indicate third-party injections, plugins, or custom frameworks worth investigating.

Checking if an app uses a specific framework

# Does this app use SwiftUI?
vmmap <pid> | grep 'SwiftUI'

# Does it link against Metal?
otool -L /path/to/binary | grep 'Metal'

FAQ

What is the difference between a dylib and a framework on macOS?

A .dylib is a standalone dynamic library file. A .framework is a bundle directory that contains a dylib along with headers, resources, and metadata. Frameworks are the standard packaging format for Apple’s system libraries and third-party SDKs. At runtime, both are loaded the same way by dyld.

Can I see which dylibs a running app uses without Terminal?

Yes. ProcXray lets you select any running process and view its loaded modules in a graphical interface with built-in search. No terminal commands needed.

Why does a process load hundreds of libraries?

macOS relies heavily on dynamic linking. Even a simple “Hello World” app written in Swift loads 100+ modules because the Swift runtime, Foundation framework, and core system libraries each pull in their own dependencies. This is normal and by design — shared libraries reduce memory usage across the system.

Does otool -L show everything a process will load?

No. otool -L only shows compile-time link dependencies. Libraries loaded at runtime via dlopen() — such as plugins, optional features, and lazy-loaded components — are not shown. Use vmmap on the running process to see the complete picture.

Do I need sudo to inspect another process’s modules?

For your own processes, no. For system processes or processes owned by other users, you may need sudo with vmmap and lsof. ProcXray will prompt for the necessary macOS permissions on first launch.

Sources and References

Download ProcXray → — free, macOS Sonoma+.