Do my summarize about the official tutorial
Command structure
<noun> <verb> [-options [optian-value]] [argument [argument...]]
For example:
breakpoint set --name foo
breakpoint set -n foo
And make a breakpoint on a set of functions,
breakpoint set --name foo --name bar
Also can set breakpoint for a method:
breakpoint set -method foo
or
breakpoint set -M foo
For a selector or specific executable image:
# for selector
breakpoint set --selector aligenLeftEdges:
or
breakpoint set -S aligenLeftEdges:
# for shlib
breakpoint set --shlib foo.dylib --name foo
or
breakpoint set -s foo.dylib -n foo
If set breakpoint to specific line of specific file:
breakpoint set --file foo.c --line 12
To give a short alias for this command:
command alias bfl breakpoint set -f %1 -l %2
# for short:
bfl foo.c 12
# or alias to a much simple single alphabet
command alias b breakpoint
Program loading
lldb "file dir" # in shell
or
(lldb) file "file dir"
Settings breakpoint
# find out about the breakpoints
(lldb) breakpoint list
After setting the breakpoint, if no locations were found, there will be the warning:
(lldb) breakpoint set --file foo.c --line 12
Breakpoint created: 2: file ='foo.c', line = 12, locations = 0 (pending)
WARNING: Unable to resolve breakpoint to any actual locations.
It just like to activate the pending
mode in gdb
(gdb) set breakpoint pending on
After setting the breakpoint successfully,
(lldb) breakpoint list
Current breakpoints:
1: name = 'alignLeftEdges:', locations = 1, resolved = 1
1.1: where = Sketch`-[SKTGraphicView alignLeftEdges:] + 33 at /Projects/Sketch/SKTGraphicView.m:1405, address = 0x0000000100010d5b, resolved, hit count = 0
Note the ID 1.1
, you can do operations on it, like:
(lldb) breakpoint command add 1.1
Enter your debugger command(s). Type 'DONE' to end.
> bt
> DONE
Here, add
can add a set of command so a breakpoint, you can find further help by:
(lldb) help break command add
Add a set of commands to a breakpoint, to be executed whenever the breakpoint is hit.
Syntax: breakpoint command add <cmd-options> <breakpt-id>
etc...
Breakpoint names
You can modify the name of breakpoint, e.g.:
(lldb) breakpoint modify -c "self == nil" -C bt --auto-continue 1 2 3
# modify : modify the breakpoint
# -c "expression" : set condition of when to break
# -C "command" : what command will be executed when break
# --auto-continue : program will not stop during lldb running
# 1 2 3 : breakpoint ID
To avoid needing to input breakpoint ID every time, it may be more simple to give a name:
breakpoint set -N SelfNil
You can also use another logical operation to do the same thing, using:
(lldb) breakpoint name configure -c "self == nil" -C bt --auto-continue SelfNil
# do breakpoint name configure operation if condition fulfiled
All command lines here are used when all the breakpoints are selected, if only one breakpoint is needed:
(lldb) breakpoint name configure -B 1 SelfNil
# only breakpoint will be selected to name as SlfNil
Setting watchpoints
Watchpoint is different from breakpoint, for breakpoint, it just include when the program stop. While watchpoint will watch the memory or the variable value changee, e.g.:
(lldb) watch set var global
Watchpoint created: Watchpoint 1: addr = 0x100001018 size = 4 state = enabled type = w
declare @ '/Volumes/data/lldb/svn/ToT/test/functionalities/watchpoint/watchpoint_commands/condition/main.cpp:12'
# tell which variable will be watched (`global` here)
(lldb) watch modify -c '(global==5)'
# tell when watch operation will be executed (`global==5` here)
(lldb) watch list
Current watchpoints:
Watchpoint 1: addr = 0x100001018 size = 4 state = enabled type = w
declare @ '/Volumes/data/lldb/svn/ToT/test/functionalities/watchpoint/watchpoint_commands/condition/main.cpp:12'
condition = '(global==5)'
# list all watchpoints and show their ID.
(lldb) c
Process 15562 resuming
(lldb) about to write to 'global'...
Process 15562 stopped and was programmatically restarted.
Process 15562 stopped and was programmatically restarted.
Process 15562 stopped and was programmatically restarted.
Process 15562 stopped and was programmatically restarted.
Process 15562 stopped
* thread #1: tid = 0x1c03, 0x0000000100000ef5 a.out`modify + 21 at main.cpp:16, stop reason = watchpoint 1
frame #0: 0x0000000100000ef5 a.out`modify + 21 at main.cpp:16
13
14 static void modify(int32_t &var) {
15 ++var;
-> 16 }
17
18 int main(int argc, char** argv) {
19 int local = 0;
# continue
(lldb) bt
* thread #1: tid = 0x1c03, 0x0000000100000ef5 a.out`modify + 21 at main.cpp:16, stop reason = watchpoint 1
frame #0: 0x0000000100000ef5 a.out`modify + 21 at main.cpp:16
frame #1: 0x0000000100000eac a.out`main + 108 at main.cpp:25
frame #2: 0x00007fff8ac9c7e1 libdyld.dylib`start + 1
# backtrace
(lldb) frame var global
(int32_t) global = 5
# watch the variable value every frame
(lldb) watch list -v
Current watchpoints:
Watchpoint 1: addr = 0x100001018 size = 4 state = enabled type = w
declare @ '/Volumes/data/lldb/svn/ToT/test/functionalities/watchpoint/watchpoint_commands/condition/main.cpp:12'
condition = '(global==5)'
hw_index = 0 hit_count = 5 ignore_count = 0
(lldb)
# give the watch point in verbose
Starting or attaching to your program
To run your program:
(lldb) process launch
(lldb) run
(lldb) r
# all of the raw command or alias are ok
If you want to attach a debugger to some process, you can do:
(lldb) process attach --pid 123
# attach the process by pid
(lldb) process attach --name Sketch
# attach the process by process name
(lldb) process attach --name Sketch --waitfor
# wait for the naxt process named Sketch to attach
After attach the debugger, when your process stop, there will output the reason, e.g.
(lldb) process attach -p 12345
Process 46915 Attaching
Process 46915 Stopped
1 of 3 threads stopped with reasons:
* thread #1: tid = 0x2c03, 0x00007fff85cac76a, where = libSystem.B.dylib`__getdirentries64 + 10, stop reason = signal = SIGSTOP, queue = com.apple.main-thread
# here we can see one of the threads is stopped because of some reason.
Controlling your program
After the program has meet the breakpoint and stop, if we hope to continue our program:
(lldb) thread continue
Resuming thread 0x2c03 in process 46915
Resuming process 46915
However, thread continue
only can make program continue until next breakpoint is meet, if we need more operations, we can do:
(lldb) thread step-in
or
(lldb) step
or
(lldb) s
# analyse the code one-by-one step.
(lldb) thread step-out
or
(lldb) next
or
(lldb) n
# continue to run the program until this function has returned, used when you are not interested in this function.
(lldb) thread step-over
or
(lldb) finish
or
(lldb) f
# continue analyse the program one-by-one step, but don't step in any other funcion, means only concentrate in this function.
If you want to have a step by instruction versions,
(lldb) thread step-inst // which is same as (gdb) stepi or (gdb) si
(lldb) thread step-over-inst // which is same as (gdb) nexti or (gdb) ni
To avoid running for too long, lldb has a run until line or frame exit stepping mode:
(lldb) thread until 100
Sometimes, we don’t want to interrupt the interface, we can use
(lldb) process launch --stdio=/path/to/logfile.txt
which can be canceled by
(lldb) settings set tartget.process.disable-stdio true
If you can set a breakpoint and stop at a function or something,
(lldb) process continue
(lldb) breakpoint set --name stop_here // stop_here is a function or some named variable
And there are commands that currently work while running include
(lldb) process interrupt
(lldb) process status
(lldb) breakpoint [set|clear|enalbe|disable|list] ...
Examining thread state
(lldb) thread list
Process 46915 state is Stopped
* thread #1: tid = 0x2c03, 0x00007fff85cac76a, where = libSystem.B.dylib`__getdirentries64 + 10, stop reason = signal = SIGSTOP, queue = com.apple.main-thread
thread #2: tid = 0x2e03, 0x00007fff85cbb08a, where = libSystem.B.dylib`kevent + 10, queue = com.apple.libdispatch-manager
thread #3: tid = 0x2f03, 0x00007fff85cbbeaa, where = libSystem.B.dylib`__workq_kernreturn + 10
The * indicates that Thread 1 is the current thread. To get a backtrace for that thread, do:
(lldb) thread backtrace
thread #1: tid = 0x2c03, stop reason = breakpoint 1.1, queue = com.apple.main-thread
frame #0: 0x0000000100010d5b, where = Sketch`-[SKTGraphicView alignLeftEdges:] + 33 at /Projects/Sketch/SKTGraphicView.m:1405
frame #1: 0x00007fff8602d152, where = AppKit`-[NSApplication sendAction:to:from:] + 95
frame #2: 0x00007fff860516be, where = AppKit`-[NSMenuItem _corePerformAction] + 365
frame #3: 0x00007fff86051428, where = AppKit`-[NSCarbonMenuImpl performActionWithHighlightingForItemAtIndex:] + 121
frame #4: 0x00007fff860370c1, where = AppKit`-[NSMenu performKeyEquivalent:] + 272
frame #5: 0x00007fff86035e69, where = AppKit`-[NSApplication _handleKeyEquivalent:] + 559
frame #6: 0x00007fff85f06aa1, where = AppKit`-[NSApplication sendEvent:] + 3630
frame #7: 0x00007fff85e9d922, where = AppKit`-[NSApplication run] + 474
frame #8: 0x00007fff85e965f8, where = AppKit`NSApplicationMain + 364
frame #9: 0x0000000100015ae3, where = Sketch`main + 33 at /Projects/Sketch/SKTMain.m:11
frame #10: 0x0000000100000f20, where = Sketch`start + 52
You can also provide a threads to backtrace or see all threads by,
(lldb) thread backtrace all
Or select to change the default current thread,
(lldb) thread select 2
Examining stack frame state
The most convenient way,
(lldb) frame variable
self = (SKTGraphicView *) 0x0000000100208b40
_cmd = (struct objc_selector *) 0x000000010001bae1
sender = (id) 0x00000001001264e0
selection = (NSArray *) 0x00000001001264e0
i = (NSUInteger) 0x00000001001264e0
c = (NSUInteger) 0x00000001001253b0
Or specify which variable
(lldb) frame variable self.isa
(struct objc_class *) self.isa = 0x0000000100023730
Which support some simple operations like &, *, ->, []
(lldb) frame variable *self
(SKTGraphicView *) self = 0x0000000100208b40
(NSView) NSView = {
(NSResponder) NSResponder = {
...
(lldb) frame variable &self
(SKTGraphicView **) &self = 0x0000000100304ab
(lldb) frame variable argv[0]
(char const *) argv[0] = 0x00007fff5fbffaf8 "/Projects/Sketch/build/Debug/Sketch.app/Contents/MacOS/Sketch"
(lldb) frame variable pStruct->field
In which,
'&' : get the variable address
'*' : get the pointer address
'->' : vist the member in struct
'[]' : get specific element in the array
When need to perform “object printing”
(lldb) frame variable -o self (SKTGraphicView *) self = 0x0000000100208b40 <SKTGraphicView: 0x100208b40>
You can select another frame to view with the "frame select" command
(lldb) frame select 9
frame #9: 0x0000000100015ae3, where = Sketch`function1 + 33 at /Projects/Sketch/SKTFunctions.m:11
basal commands
b # breakpoint
r # run
s # step in
n # next step
bt # stack
f # frame
c # continue
Usually used commands
b test.c:12 // set breakpoint
p data // print data
set -- test 1 2 3 // set parameter
bt 5 // print recent 5 layers fram
x/4xb data // print former 4 hexadecimal bytes
x/4tb data // print former 4 binary bytes
An example:
#inclue <stdio.h>
void to_upper(char *data) {
for(int i = 0; data; i++)} {
if(data[i] > = 'a' && data[i] <= 'z') {
data[i] -= 32
}
printf("data = %s", data)
}
}
int main(int argv, char** argc) {
char *data = "Hello, World";
to_upper(data);
puts("main end.");
return 0};
}
$ gcc -g test.c -o test // -g save the debug information
$ lldb // enter lldb
(lldb) file test // input the file test
(lldb) settings set target.run-args helloword // give the args in test.c (helloword)
(lldb) b test.c:12 // give the breakpoint at line 12
(lldb) r // run
(lldb) p argv // print argv
(lldb) p argc[0] // print argc[0] -> the file path
(lldb) p argc[1] // print argc[1] -> "Hello, Word"
(11db) p argc[2] // blank value
(11db) s // enter the function
(11db) n // step out
(11db) q // quit