LLDB

DebuggingSwiftC/C++Objective-CXcodeAppleLLVMiOSmacOS

Debugging Tool

LLDB

Overview

LLDB is a high-performance debugger from the LLVM project. It supports C, C++, Objective-C, and Swift, and is the default debugger in Xcode, making it standard for macOS/iOS development.

Details

LLDB (Low-Level Debugger) is a next-generation, high-performance debugger developed as part of the LLVM (Low Level Virtual Machine) project. Apple began its development in 2010, and it has been adopted as the default debugger for Xcode 5 and later. LLDB supports multiple languages including C, C++, Objective-C, and Swift, providing excellent functionality especially for Swift language integration.

As the standard debugger in Apple environments, its importance has increased with Swift language adoption, making it essential for macOS, iOS, watchOS, and tvOS development. It's also gradually expanding adoption in Linux environments with advancing cross-platform support.

In 2024's latest features, Swift 6's @DebugDescription macro support allows customizing the output of p command and variable viewer directly from source code. LLDB includes fully functioning Swift and Clang compilers, enabling expression evaluator capabilities that go beyond variable inspection to perform computation, call functions, and change program state.

It provides Python scripting APIs for advanced debugging workflows including automation of repetitive tasks, inspection of deeply nested objects, and dynamic variable manipulation. Tight integration with Swift REPL provides interactive development and debugging experiences.

Pros and Cons

Pros

  • High Performance: Excellent execution performance with LLVM architecture
  • Full Swift Support: Specialized features optimized for Swift debugging
  • Xcode Integration: Seamless integration with Apple development environment
  • Rich Expression Evaluation: Advanced expression evaluation with full compilers
  • Python Scripting: Powerful automation and customization capabilities
  • REPL Integration: Tight integration with Swift REPL
  • Cross-Platform: Runs on macOS, Linux, FreeBSD, Windows
  • Modern Architecture: Latest debugging technology and design patterns

Cons

  • Apple Environment Dependency: Primarily specialized for Apple development ecosystem
  • Learning Curve: Need to master different command system from GDB
  • Limited Documentation: Fewer tutorial resources compared to GDB
  • Linux Support Limitations: Functional restrictions in Linux environments
  • Complex Configuration: Complicated setup for advanced features
  • Memory Usage: High memory consumption due to rich functionality
  • Smaller Community: Smaller community compared to GDB

Key Links

Usage Examples

LLDB Startup and Basic Operations

# Start program with LLDB
lldb ./myprogram

# Attach to running process
lldb -p <process_id>

# Start Swift REPL mode
swift
# or
lldb --repl

# Core dump analysis
lldb -c core ./myprogram

Basic LLDB Commands

# Run program
(lldb) run
(lldb) r

# Run with arguments
(lldb) run arg1 arg2
(lldb) settings set target.run-args arg1 arg2

# Set breakpoints
(lldb) breakpoint set --name main
(lldb) b main
(lldb) breakpoint set --file main.swift --line 25
(lldb) br s -f main.swift -l 25

# List breakpoints
(lldb) breakpoint list
(lldb) br list

# Delete breakpoints
(lldb) breakpoint delete 1
(lldb) br del 1

Program Execution Control

# Step into (enter functions)
(lldb) step
(lldb) s

# Step over (skip functions)
(lldb) next
(lldb) n

# Step out (exit functions)
(lldb) finish
(lldb) f

# Continue execution
(lldb) continue
(lldb) c

# Run until specified line
(lldb) thread until 30

Variable and Memory Inspection

# Print variable values
(lldb) print variable_name
(lldb) p variable_name
(lldb) po object_name        # Object description

# Swift variable detailed display
(lldb) v variable_name       # Variable details
(lldb) fr var               # All variables in frame

# Memory reading
(lldb) memory read 0x12345678
(lldb) mem read -s 1 -f x -c 16 0x12345678

# Change variable values
(lldb) expr variable_name = new_value
(lldb) expression -- variable_name = new_value

Backtrace and Stack Information

# Display backtrace
(lldb) thread backtrace
(lldb) bt

# All threads backtrace
(lldb) thread backtrace all
(lldb) bt all

# Select stack frame
(lldb) frame select 0
(lldb) f 0

# Display frame information
(lldb) frame info
(lldb) frame variable        # Frame variables

Swift-Specific Debugging Features

# Evaluate Swift expressions
(lldb) expression let result = someFunction()
(lldb) expr -l swift -- let x = 10

# Dump Swift objects
(lldb) po myObject
(lldb) expr -O -- myObject

# Display Swift type information
(lldb) type lookup Swift.String
(lldb) image lookup -t String

# Invoke Swift REPL
(lldb) repl

Advanced Debugging Features

# Conditional breakpoints
(lldb) breakpoint set --name main --condition 'argc > 1'
(lldb) br s -n main -c 'argc > 1'

# Watchpoints
(lldb) watchpoint set variable variable_name
(lldb) wa s v variable_name

# Exception breakpoints
(lldb) breakpoint set -E swift
(lldb) breakpoint set -E objc

# Function calls
(lldb) call function_name(args)
(lldb) expression function_name(args)

Thread and Process Management

# List threads
(lldb) thread list

# Switch threads
(lldb) thread select 2

# Process information
(lldb) process status
(lldb) process continue
(lldb) process kill

# Signal handling
(lldb) process handle SIGINT -s true -p true

LLDB Customization

# Custom command definitions (~/.lldbinit)
command alias bd breakpoint disable
command alias be breakpoint enable

# Python scripting
script
import lldb

def hello_command(debugger, command, result, internal_dict):
    print("Hello from LLDB!")

lldb.debugger.HandleCommand('command script add -f script.hello_command hello')
script

# Settings changes
(lldb) settings set target.x86-disassembly-flavor intel
(lldb) settings set thread-format "thread #${thread.index}: tid = ${thread.id}{, pc = ${frame.pc}}"

Practical Examples for iOS/macOS Development

# Check ViewController properties
(lldb) po self.view
(lldb) po [self.view recursiveDescription]

# Runtime UI changes
(lldb) expr self.view.backgroundColor = UIColor.red
(lldb) expr (void)[CATransaction flush]

# Check Core Data objects
(lldb) po managedObjectContext.registeredObjects

# Swift Concurrency debugging
(lldb) thread list
(lldb) bt

Python Script Automation

# ~/.lldbinit or independent Python file
import lldb

def print_all_variables(debugger, command, result, internal_dict):
    target = debugger.GetSelectedTarget()
    process = target.GetProcess()
    thread = process.GetSelectedThread()
    frame = thread.GetSelectedFrame()
    
    variables = frame.GetVariables(True, True, True, True)
    for var in variables:
        print(f"{var.name} = {var.value}")

def __lldb_init_module(debugger, internal_dict):
    debugger.HandleCommand('command script add -f mymodule.print_all_variables pav')

Expression Evaluation and REPL Usage

# Complex expression evaluation
(lldb) expr import Foundation
(lldb) expr let url = URL(string: "https://example.com")
(lldb) po url

# Define and execute temporary functions
(lldb) expr func debugHelper() -> String { return "Debug info" }
(lldb) po debugHelper()

# Inline Swift code execution
(lldb) expr -l swift -- 
    let formatter = DateFormatter()
    formatter.dateStyle = .full
    print(formatter.string(from: Date()))