LLDB is the default debugger for Xcode and a powerful command-line debugger for macOS, iOS, and Linux. This guide covers debugging commands, breakpoints, expressions, and scripting.
Installation
macOS
# Usually included with Xcode
xcode-select --install
# Or install Xcode from App Store
# Command line tools available at: developer.apple.com
# Verify installation
lldb --version
Linux
# Ubuntu/Debian
sudo apt update
sudo apt install lldb
# Fedora/RHEL
sudo dnf install lldb
# Build from source
git clone https://github.com/llvm/llvm-project.git
cd llvm-project && mkdir build && cd build
cmake -DLLVM_ENABLE_PROJECTS=lldb ../llvm
make -j$(nproc)
Verify Installation
lldb --version
lldb --help
Starting a Debug Session
Launching Executables
# Debug an executable
lldb ./myprogram
# Debug with arguments
lldb -- ./myprogram arg1 arg2
# Attach to running process
lldb -p <PID>
lldb -n <process_name>
# Debug with working directory
lldb -C <dir> ./myprogram
Command Modes
# Interactive mode (default)
lldb ./program
# Run command and exit
lldb -o "run" -o "continue" ./program
# Run script file
lldb -s commands.lldb ./program
Essential Commands
Process Control
| Command | Alias | Description |
|---|
run or r | r | Start execution |
continue | c | Resume from breakpoint |
step | s | Step into next line |
step-inst | si | Step into next instruction |
next | n | Step over next line |
next-inst | ni | Step over next instruction |
finish | fin | Continue until return |
kill | k | Kill target process |
Breakpoints
| Command | Description |
|---|
breakpoint set -n <func> | Break at function |
b <func> | Break at function (alias) |
breakpoint set -a <addr> | Break at address |
breakpoint set -f <file> -l <line> | Break at file:line |
b file.c:100 | Break at line 100 in file.c |
breakpoint list | List all breakpoints |
breakpoint delete <#> | Delete breakpoint |
breakpoint disable <#> | Disable breakpoint |
Examination
| Command | Description |
|---|
frame variable | Show local variables |
frame variable <var> | Show specific variable |
memory read <addr> <count> | Read memory at address |
register read | Show all registers |
register read <reg> | Show specific register |
backtrace or bt | Show call stack |
thread list | Show all threads |
disassemble | Disassemble current function |
Breakpoints
Setting Breakpoints
# Function breakpoint
(lldb) breakpoint set -n main
(lldb) b main
# Line number breakpoint
(lldb) breakpoint set -f myfile.c -l 42
(lldb) b myfile.c:42
# Address breakpoint
(lldb) breakpoint set -a 0x100000000
(lldb) b -a 0x100000000
# Conditional breakpoint
(lldb) breakpoint set -n malloc -c 'size > 1000'
(lldb) b malloc -c 'size > 1000'
Managing Breakpoints
# List all breakpoints
breakpoint list
# Delete breakpoint
breakpoint delete 1
breakpoint delete --all
# Disable/enable breakpoint
breakpoint disable 1
breakpoint enable 1
# Set breakpoint with action
breakpoint set -n foo -C "p myvar"
Variables and Expressions
Examining Variables
# Show all local variables
frame variable
# Show specific variable
frame variable my_var
# Show variable with custom format
frame variable --format binary my_var
frame variable --format hex my_var
# Dereference pointer
frame variable *ptr
frame variable ptr->field
# Show variable and children
frame variable --format tree my_struct
Evaluating Expressions
# Evaluate expression in current context
(lldb) expression count + 5
(lldb) expr count + 5
(lldb) p count + 5
# Call function
(lldb) expr printf("Debug: %d\n", myvar)
(lldb) po [NSString stringWithFormat:@"%@", myObj]
# Modify variable
(lldb) expr myvar = 42
(lldb) expr ptr = 0x12345678
Memory Inspection
Reading Memory
# Read memory at address
memory read 0x7ffeefbff000
# Read specific count
memory read 0x7ffeefbff000 0x7ffeefbff040
# Read with format
memory read --format x --count 16 0x7ffeefbff000
memory read --format c --count 32 0x7ffeefbff000
# Search for bytes
memory read --outfile /tmp/dump.bin --format uint32_t 0x100000000 0x100100000
Writing Memory
# Write bytes at address
memory write 0x7ffeefbff000 0x48 0x89 0xc3
# Write string
memory write 0x7ffeefbff000 -i "test string"
Watchpoints
Setting Watchpoints
# Watch variable for changes
watchpoint set variable myvar
# Watch memory location
watchpoint set expression &myvar
# Watch with size specification
watchpoint set expression &myvar --size 8
# Watch for read
watchpoint set expression &myvar -w read
# Watch for write
watchpoint set expression &myvar -w write
# Watch for read or write
watchpoint set expression &myvar -w read_write
Managing Watchpoints
# List watchpoints
watchpoint list
# Delete watchpoint
watchpoint delete 1
# Disable/enable
watchpoint disable 1
watchpoint enable 1
Stack and Frames
Examining Stack
# Show call stack
backtrace
bt
# Show detailed stack
backtrace all
# Show stack of specific thread
bt 2
# Show number of frames
frame count
# Change current frame
frame select 2
f 2
# Show frame variables
frame variable
# Show current frame details
frame info
# Show caller
frame select -r 1 ; Select previous frame
# Address of current function
p (void*)&main
Register and Instruction Level
Registers
# Show all registers
register read
# Show specific register
register read rax
register read --format binary rax
# Write register
register write rax 0x0
# Show floating point registers
register read --all
Disassembly
# Disassemble current function
disassemble
# Disassemble at address
disassemble --start-address 0x100000000
# Disassemble with context
disassemble --count 20 --start-address 0x100000000
# Format options
disassemble --format intel ; Intel syntax
disassemble --format att ; AT&T syntax
Thread Debugging
Thread Commands
# List threads
thread list
# Select thread
thread select 2
thread select --index 2
# Show thread info
thread info
# Break all threads
thread backtrace all
Thread Control
# Pause thread
thread suspend 1
# Resume thread
thread resume 1
# Single step in thread
thread step-in
thread step-over
thread step-out
Python Scripting
Python Commands
# Execute Python inline
(lldb) script print("hello from Python")
# Import modules
(lldb) script import os; print(os.path.expanduser("~"))
# Access LLDB API
(lldb) script lldb.debugger.GetSelectedTarget()
Script Files
# File: lldb_script.py
import lldb
def say_hello(debugger, command, result, internal_dict):
print("Hello from LLDB Python!")
def __lldb_init_module(debugger, internal_dict):
debugger.HandleCommand('command script add -f lldb_script.say_hello hello')
# Load Python script
command script import /path/to/script.py
# Use custom command
hello
Debugging Strategies
Finding Memory Leaks
# Set watchpoint on allocation
breakpoint set -n malloc
commands add -s python << 'EOF'
frame variable size
EOF
# Trace frees
breakpoint set -n free
b free -C "p ptr"
# Use malloc stack logging (macOS)
export MallocStackLogging=1
export MallocStackLoggingNoCompact=1
./myprogram
Finding Crashes
# Set exception breakpoint
breakpoint set -E cpp
breakpoint set -E objc
# Catch crashes
breakpoint set -n abort
breakpoint set -n assert
# Run until crash
run
# When crash occurs, examine stack
bt
frame variable
# Conditional breakpoint to count calls
b myfunction -c 1 -C "p ++count"
# Measure execution time
expr (unsigned long long)(&main)
# Note timestamp
n
# Note new timestamp
# Calculate difference
Common Debugging Tasks
Debug a Segmentation Fault
1. Run program: (lldb) run
2. Program crashes with SIGSEGV
3. Show backtrace: bt
4. Show registers: register read
5. Show memory: memory read 0x<addr>
6. Examine frame variables: frame variable
7. Set breakpoints before crash: b <line>
8. Rerun and step through carefully
Debug Objective-C Code
# Set breakpoint on method
breakpoint set -n "[NSString init]"
b "[NSString init]"
# Print Objective-C object
po self
po [self description]
# Call Objective-C method
expr (void)[myObj doSomething]
# Inspect ivar
frame variable _myIvar
Debug C++ Code
# Set breakpoint in namespace
breakpoint set -n "std::vector::push_back"
b "std::vector::push_back"
# Print C++ object
expr myobject
p *(MyClass*)0x7fff5fbff000
# Show virtual methods
disassemble --name "_ZN7MyClass6methodEv"
Tips and Best Practices
- Use
frame variable to inspect locals before inspecting memory
- Set breakpoints on external function calls to understand flow
- Use expressions to modify variables and test behavior
- Combine breakpoints with conditions for targeted debugging
- Use watchpoints to find where variables are modified
- Script repetitive debugging tasks in Python
- Use
memory read to inspect raw memory at suspicious addresses
- Set breakpoints at function entry to trace call patterns
- Use
disassemble to understand assembly-level behavior
- Examine registers and stack for low-level debugging
Resources
Last updated: 2026-03-30