LLDB
Contract
| Field | Bound contract |
|---|---|
| Trigger | A program needs debugging with LLDB on macOS, FreeBSD, or a clang-built Linux tree, a GDB habit needs its LLDB equivalent, or LLDB needs driving from Xcode, VS Code, or Python. |
| Authority | Read-only. Emits analysis and commands for the operator to run on the target; no file writes, no rollback needed. No remote mutation. |
| Side effect | Diagnostic commands and a verdict in chat. Nothing is written. |
| Done | The bug is localized to a frame, variable, or instruction, or the GDB-to-LLDB mapping for the needed command is given. |
Inputs
- Binary (required): built with
-g. - Symptom (required): crash, hang, wrong value, or a GDB command that needs its LLDB form.
- Core file or PID (optional): for post-mortem or attach workflows.
Procedure
Start the session.
lldb ./prog # load a binary lldb ./prog -- arg1 arg2 # with arguments lldb -p 12345 # attach to a PID lldb -c core.1234 # load a core lldb ./prog core.1234 # binary plus coreDone when: LLDB has a live process or a loaded core.
Map GDB habits to LLDB. The common cases:
GDB LLDB run [args]process launch [args]/rcontinueprocess continue/cnextthread step-over/nstepthread step-in/snextithread step-inst-over/nistepithread step-inst/sifinishthread step-out/finishbreak mainbreakpoint set -n main/b mainbreak file.c:42breakpoint set -f file.c -l 42/b file.c:42break *0x400abcbreakpoint set -a 0x400abc/b -a 0x400abcwatch xwatchpoint set variable x/wa s v xprint xframe variable x/p xinfo localsframe variable/fr vbacktracethread backtrace/btframe Nframe select N/f Ninfo threadsthread listthread apply all btthread backtrace allx/10wx addrmemory read -s4 -fx -c10 addr/x/10xw addrset var = 42expression var = 42/expr var = 42The full map lives in
references/gdb-lldb-map.md. Done when: the needed command has its LLDB form.Set breakpoints.
b main breakpoint set --name foo --condition 'x > 0' b file.c:42 breakpoint set --file file.c --line 42 b -a 0x100003f20 # address breakpoint set --func-regex '^MyClass::' # regex breakpoint set -o -n foo # one-shot breakpoint list # br l breakpoint delete 2 breakpoint disable 1 / breakpoint enable 1 breakpoint command add 1 # commands on hit, end with DONEDone when: execution stops at the condition that matters.
Inspect state.
p x / p *ptr / p arr[0] frame variable # arguments and locals expression x * 2 + 1 # evaluate any expression register read / register read rip rsp memory read --size 4 --format x --count 10 0x7fff0000 x/10xw 0x7fff0000 # GDB-compatible syntax works image lookup --type MyClass # type info type lookup MyClassDone when: the variable, register, or memory region in question is read.
Set watchpoints.
watchpoint set variable x # write watchpoint watchpoint set variable -w read x # read watchpoint watchpoint set variable -w read_write x watchpoint set expression -- &x # by address watchpoint list / watchpoint delete 1Done when: the write or read that corrupts state is trapped.
Debug threads.
thread list thread select 3 thread backtrace all thread backtrace --count 5 thread step-over # steps this thread onlyDone when: each thread's state is known.
Use the Apple-specific surface.
image lookup --address 0x18ab12345 # symbol in the shared cache image lookup --name objc_msgSend b "-[NSArray objectAtIndex:]" # Objective-C method breakpoint po myObject # print-object, calls -description image list / image list -b # loaded librariesDone when: Objective-C or shared-cache frames resolve.
Drive LLDB from VS Code. Install the CodeLLDB extension and add a
launch.jsonconfiguration:{ "name": "Debug (lldb)", "type": "lldb", "request": "launch", "program": "${workspaceFolder}/build/prog", "args": [], "cwd": "${workspaceFolder}", "preLaunchTask": "build" }Done when: F5 launches the program under LLDB.
Script LLDB with Python.
import lldb def print_all_threads(debugger, command, result, internal_dict): target = debugger.GetSelectedTarget() process = target.GetProcess() for thread in process: print(f"Thread {thread.GetIndexID()}: {thread.GetName()}") for frame in thread: print(f" {frame}") def __lldb_init_module(debugger, internal_dict): debugger.HandleCommand('command script add -f myscript.print_all_threads pthreads')Load with
command script import /path/to/myscript.py. Done when: the script command runs inside LLDB.
Failure and recovery
<unavailable>for a variable: the value was optimized out; seedebug-optimized-builds.- A GDB command has no LLDB form: check
references/gdb-lldb-map.md; where no equivalent exists, the table says so. - Breakpoint on an Objective-C method misses: quote the full selector,
b "-[Class method:]". expressionfails on a function call: the function may be inlined or stripped; call it by address or evaluate the expression manually.- Core will not load: confirm the binary matches the core;
target create ./prog --core coreneeds the exact executable.
Output
The bug localized to a frame, variable, register, or instruction, with the LLDB commands that produced the evidence; or the GDB-to-LLDB mapping for the command that was asked about.