1、指令格式
例如给test函数设置断点:
(lldb) breakpoint set -n test
void test()
{
int a = 10;
int b = 20;
NSLog(@"a + b = %d", a + b);
}
其中breakpoint是
,set是 ,-n是 ,test是
2、help
查看指令的用法。例如查看breakpoint指令用法:
(lldb) help breakpoint
clear -- Delete or disable breakpoints matching the specified source
file and line.
command -- Commands for adding, removing and listing LLDB commands
executed when a breakpoint is hit.
delete -- Delete the specified breakpoint(s). If no breakpoints are
specified, delete them all.
disable -- Disable the specified breakpoint(s) without deleting them. If
none are specified, disable all breakpoints.
enable -- Enable the specified disabled breakpoint(s). If no breakpoints
are specified, enable all of them.
3、expression —
3.1、执行一个表达式
—:命令选项结束符,表示所有的命令选项已经设置完毕,如果没有命令选项,—可以省略
例如设置view的边框宽度:
(lldb) expression self.view.layer.borderWidth = 30
3.2、打印对象信息
expression、expression —、print、p、call的效果一样,例如打印array的信息:
(lldb) p array
(NSConstantArray *) $0 = 0x000000010c21f538 @"3 elements"
3.3、打印对象描述
expression、-O —和指令 po 的效果一样,例如打印array的描述:
(lldb) po array
<NSConstantArray 0x10c21f538>(
1,
2,
3
)
4、thread
4.1、thread backtrace
打印线程的堆栈信息。和指令 bt 效果一样,比如在touchesBegan:withEvent:添加断点,执行:
(lldb) bt
...
frame #0: 0x000000010c217ed6 LLDB指令`-[ViewController touchesBegan:withEvent:](self=0x00007fafb170b800, _cmd="touchesBegan:withEvent:", touches=1 element, event=0x0000600000f30300) at ViewController.m:32:5
frame #1: 0x00007fff250d4f2e UIKitCore`forwardTouchMethod + 312
frame #2: 0x00007fff250e5b33 UIKitCore`-[UIWindow _sendTouchesForEvent:] + 617
frame #3: 0x00007fff250e7e3a UIKitCore`-[UIWindow sendEvent:] + 5312
frame #4: 0x00007fff250bdeac UIKitCore`-[UIApplication sendEvent:] + 820
frame #5: 0x00007fff25155f0a
...
frame:栈帧,每一帧代表一个函数调用
4.2、thread return []
让函数直接返回某个值,不会执行断点后面的代码。例如让test方法在断点处返回:
void test()
{
int a = 10;
int b = 20;
NSLog(@"a + b = %d", a + b);
}
(lldb) thread return
输入thread return指令后,就不会再执行NSLog打印。
4.3、frame variable []
打印当前栈帧的变量。例如打印test方法中的变量:
void test()
{
int a = 10;
int b = 20;
NSLog(@"a + b = %d", a + b);
}
(lldb) frame variable
(int) a = 10
(int) b = 20
5、流程控制
5.1、源码级别
thread continue、continue、c:程序继续运行
thread step-over、next、n:单步运行,把子函数当作一个整体一步执行
thread step-in、step、s:单步运行,遇到子函数会进入子函数
thread step-out、finish:直接执行完当前函数的所有代码,返回到上一个函数
5.2、汇编指令级别
thread step-inst-over、nexti、ni:单步运行,把子函数当作一个整体一步执行
thread step-inst、stepi、si:单步运行,遇到子函数会进入子函数
ni、si 类似于 n 和 s ,例如在调试汇编代码时,通过si指令让汇编代码单步运行,遇到子函数会进入子函数:
LLDB指令`test:
0x108a63e50 <+0>: pushq %rbp
-> 0x108a63e51 <+1>: movq %rsp, %rbp
0x108a63e54 <+4>: subq $0x10, %rsp
0x108a63e58 <+8>: movl $0xa, -0x4(%rbp)
...
6、代码断点
6.1、breakpoint set
代码断点有以下设置方式:
breakpoint set -a 函数地址
breakpoint set -n 函数名
breakpoint set -r 正则表达式
breakpoint set -s 动态库 -n 函数名
例如给所有touchesBegan:withEvent:方法添加断点:
(lldb) breakpoint set -n touchesBegan:withEvent:
例如给ViewController的touchesBegan:withEvent:添加断点:
(lldb) breakpoint set -n “-[ViewController touchesBegan:withEvent:]”
例如给所有函数名包含Began的函数添加断点:
(lldb) breakpoint set -r Began
// 共添加了239处断点
Breakpoint 4: 239 locations.
6.2、breakpoint list
列出所有的断点(每个断点都有自己的编号)
(lldb) breakpoint list:
Current breakpoints:
1: file = '/Users/mxl/Desktop/LLDB指令/LLDB指令/ViewController.m', line = 19, exact_match = 0, locations = 1, resolved = 1, hit count = 1
1.1: where = LLDB指令`-[ViewController viewDidLoad] + 16 at ViewController.m:19:5, address = 0x0000000101a8ae20, resolved, hit count = 1
2: file = '/Users/mxl/Desktop/LLDB指令/LLDB指令/ViewController.m', line = 33, exact_match = 0, locations = 1, resolved = 1, hit count = 0
2.1: where = LLDB指令`-[ViewController touchesBegan:withEvent:] + 105 at ViewController.m:33:5, address = 0x0000000101a8aee9, resolved, hit count = 0
3: file = '/Users/mxl/Desktop/LLDB指令/LLDB指令/ViewController.m', line = 24, exact_match = 0, locations = 1, resolved = 1, hit count = 0
3.1: where = LLDB指令`test + 8 at ViewController.m:24:9, address = 0x0000000101a8ae58, resolved, hit count = 0
6.3、编辑断点
breakpoint disable 断点编号:禁用断点
breakpoint enable 断点编号:启用断点
breakpoint delete 断点编号:删除断点
例如删除3号断点:
(lldb) breakpoint delete 3
1 breakpoints deleted; 0 breakpoint locations disabled.
7、断点命令
breakpoint command add 断点编号:给断点预先设置需要执行的命令,到触发断点时,就会按顺序执行
breakpoint command list 断点编号:查看某个断点设置的命令
breakpoint command delegate 断点编号:删除某个断点设置的命令
例如给断点添加打印信息:
(lldb) breakpoint command add 1
Enter your debugger command(s). Type 'DONE' to end.
> p self
> po self
> DONE
当执行到断点时:
p self
(ViewController *) $0 = 0x00007fc302808460
po self
<ViewController: 0x7fc302808460>
8、内存断点
内存断点会在内存数据发生改变的时候触发,常见用法有:
watchpoint set variable 变量:给变量添加一个内存断点。例如给ViewController的age属性添加一个内存断点:
(lldb) watchpoint set variable self->_age
当age的内容更新时,会触发这个内存断点
Watchpoint 1 hit:
old value: 0
new value: 20
watchpoint set expresion 地址,通过地址添加内存断点,例如给age属性添加一个内存断点:
(lldb) watchpoint set expression 0x00007fe7d34074b0
内存断点还有其它用法:
watchpoint list
watchpoint disable 断点编号
watchpoint enable 断点编号
watchpoint delete 断点编号
watchpoint command add 断点编号
watchpoint command list 断点编号
watchpoint command delete 断点编号
9、模块查找
9.1、image lookup
image lookup -t 类型:查找某个类型的信息
image loopup -a 地址:根据内存地址查找在模块中的位置
image loopup -n 符号或者函数名:查找某个符号或者函数的位置
例如查看NSArray的信息:
(lldb) image lookup -t NSArray
Best match found in /Users/mengxianliang/Library/Developer/Xcode/DerivedData/LLDB指令-gmoomcnqyjazkcgbagyhcjflphbb/Build/Products/Debug-iphonesimulator/LLDB指令.app/LLDB指令:
id = {0x000002a8}, name = "NSArray", byte-size = 8, decl = NSArray.h:17, compiler_type = "@interface NSArray : NSObject
@property(readonly, getter = count, setter = <null selector>) NSUInteger count;
@end"
再例如找出那一句代码出错,先创建一段报错的代码:
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
NSArray *array = @[@1, @2, @3];
array[3];
}
当代码触发后,控制台会报错,并打印错误信息和代码内存地址,但并不会显示哪一行代码出错:
*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSConstantArray objectAtIndexedSubscript:]: index 3 beyond bounds [0 .. 2]'
*** First throw call stack:
(
0 CoreFoundation 0x00007fff20405604 __exceptionPreprocess + 242
1 libobjc.A.dylib 0x00007fff201a4a45 objc_exception_throw + 48
2 CoreFoundation 0x00007fff20486c63 _CFThrowFormattedException + 200
3 CoreFoundation 0x00007fff2033d8d7 +[NSConstantArray new] + 0
4 LLDB指令 0x0000000104d02eac -[ViewController touchesBegan:withEvent:] + 108
...
(lldb) image lookup -a 0x0000000104d02eac
Address: LLDB指令[0x0000000100001eec] (LLDB指令.__TEXT.__text + 220)
Summary: LLDB指令`-[ViewController touchesBegan:withEvent:] + 108 at ViewController.m:41:5
打印信息包含了出错代码所在的类和行号
9.1、image list
image list:列出加载的模块信息
(lldb) image list
[ 0] B0C39DEA-9596-3495-A9CE-6FF30D2F6C78 0x000000010c4bb000 /Users/mengxianliang/Library/Developer/Xcode/DerivedData/LLDB指令-gmoomcnqyjazkcgbagyhcjflphbb/Build/Products/Debug-iphonesimulator/LLDB指令.app/LLDB指令
[ 1] DD9E80DE-FB3B-349B-96A4-46874AD34D11 0x00000001158ff000 /usr/lib/dyld
[ 2] 7276A69B-E3B9-3F23-957F-061350A501B4 0x000000010c6d7000 /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/usr/lib/dyld_sim
[ 3] 7C8E1422-6C6B-3EC0-8143-C71B8F4FE7B8 0x00007fff6fdd1000 /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/usr/lib/libBacktraceRecording.dylib
image list -o -f:打印出模块的编译地址、全路径
image代表模块
10、Tips
- 敲Enter会自动执行上一次的命令
- 绝大部份指令都可以使用缩写