一、简介
LLDB
全称是Low Lever Debug
。
下断点快捷键
command + \
二、LLDB断点设置
2.1 设置断点
breakpoint set -n XXX
set
是子命令,-n
是选项 是--name
的缩写。
Breakpoint 2: where = 001--LLDB`test1 + 8 at ViewController.m:19, address = 0x00000001000766d8
解释:
项目中的第二个断点,即为编号。
where = 001--LLDB test1 + 8 at ViewController.m:19:断点的位置,
工程名为001--LLDB,
在 ViewController.m中的第19行,
方法名为test1,
address = 0x00000001000766d8:内存地址。
2.2 OC方法设置断点
breakpoint set -n "[控制器名称 方法名称]"
Breakpoint 1: 3 locations.
解释:
1:第一组断点
3:三个地方
2.3 查看断点列表
breakpoint list
2.4 禁用/启用断点
breakpoint disable
禁用
breakpoint enable
启用
2.4.1 禁用/启用一组
禁用启用
breakpoint enable 组号
2.4.2 禁用/启用某一个断点
禁用/启用某一个断点2.5 删除断点
2.5.1 删除某组的某一个
breakpoint delete 组号
注意:可以看出它只是把它禁用了,并没有删除
删除某一组的某一个的结果
2.5.2 删除某组
breakpoint delete 组号
2.5.3 删除所有组
breakpoint delete
2.6 查看指令
2.6.1 查看lldb
所有指令
help
2.6.2 查看lldb
中子指令的所有指令
help breakpoint
2.7 遍历整个项目中所有方法名为 touchesBegan:withEvent:
breakpoint set --selector touchesBegan:withEvent:
我们点击一下,可以看出第一个断点地方是系统方法,并非是我们自己写的方法
第一个断点的地方
2.8 遍历特定文件中所有方法名为 touchesBegan:withEvent:
breakpoint set --file ViewController.m --selector touchesBegan:withEvent:
2.9 遍历整个项目中满足Game:这个字符的所有方法
breakpoint set -r Game:
2.10 流程控制
2.10.1 继续执行
$c(continue)
2.10.2 单步运行,将子函数当做整体一步执行
$n(next)
2.10.3 单步运行,遇到子函数会进去
$s
三、LLDB代码执行
3.1 查看子控件
expression self.view.subviews
问题1:指令
p
与expression
的关系如何呢?p
答案:不难看出
p
是expression
的简写形式简写形式
问题2:指令
po
又是啥呢?help expression
help expression
答案:
po
其实就是调用了OC
的description
方法
3.2 p
和po
的应用
添加数据
四、查看堆栈信息
4.1 查看堆栈信息
bt
(lldb) b test4
Breakpoint 1: where = 001--LLDB调试`-[ViewController test4] + 20 at ViewController.m:54:5, address = 0x000000010017e064
(lldb) c
Process 10967 resuming
2019-12-07 21:33:15.468965+0800 001--LLDB调试[10967:3499830] -[ViewController test1]
2019-12-07 21:33:15.469210+0800 001--LLDB调试[10967:3499830] -[ViewController test2]
2019-12-07 21:33:15.469313+0800 001--LLDB调试[10967:3499830] -[ViewController test3]
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
* frame #0: 0x000000010017e064 001--LLDB调试`-[ViewController test4](self=0x000000010072db50, _cmd="test4") at ViewController.m:54:5
frame #1: 0x000000010017e044 001--LLDB调试`-[ViewController test3](self=0x000000010072db50, _cmd="test3") at ViewController.m:50:5
frame #2: 0x000000010017dfe8 001--LLDB调试`-[ViewController test2](self=0x000000010072db50, _cmd="test2") at ViewController.m:45:5
frame #3: 0x000000010017df8c 001--LLDB调试`-[ViewController test1](self=0x000000010072db50, _cmd="test1") at ViewController.m:41:5
frame #4: 0x000000010017e3a0 001--LLDB调试`-[ViewController touchesBegan:withEvent:](self=0x000000010072db50, _cmd="touchesBegan:withEvent:", touches=1 element, event=0x00000002839e0640) at ViewController.m:86:5
frame #5: 0x000000019053eb64 UIKitCore`forwardTouchMethod + 328
frame #6: 0x000000019053ea08 UIKitCore`-[UIResponder touchesBegan:withEvent:] + 60
frame #7: 0x000000019054caf0 UIKitCore`-[UIWindow _sendTouchesForEvent:] + 1692
frame #8: 0x000000019054e0a8 UIKitCore`-[UIWindow sendEvent:] + 3352
frame #9: 0x000000019052aae8 UIKitCore`-[UIApplication sendEvent:] + 336
frame #10: 0x00000001905a223c UIKitCore`__dispatchPreprocessedEventFromEventQueue + 5880
frame #11: 0x00000001905a4798 UIKitCore`__handleEventQueueInternal + 4924
frame #12: 0x000000019059d60c UIKitCore`__handleHIDEventFetcherDrain + 108
frame #13: 0x000000018c4827e0 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 24
frame #14: 0x000000018c482738 CoreFoundation`__CFRunLoopDoSource0 + 80
frame #15: 0x000000018c481ed0 CoreFoundation`__CFRunLoopDoSources0 + 180
frame #16: 0x000000018c47d01c CoreFoundation`__CFRunLoopRun + 1080
frame #17: 0x000000018c47c8bc CoreFoundation`CFRunLoopRunSpecific + 464
frame #18: 0x00000001962e8328 GraphicsServices`GSEventRunModal + 104
frame #19: 0x00000001905126d4 UIKitCore`UIApplicationMain + 1936
frame #20: 0x000000010017e4d0 001--LLDB调试`main(argc=1, argv=0x000000016fc878a8) at main.m:14:16
frame #21: 0x000000018c307460 libdyld.dylib`start + 4
(lldb)
4.2 查看上下方法
4.2.1 断点断住test3
方法,这里的frame #0
是方法编号,之后会用到。
断住test3
4.2.2 up
上一个方法
up
4.2.3 down
下一个方法
down
4.2.4 frame select 编号
直接跳转到某个方法
跳转到某个方法
4.2.5 frame variable
打印方法参数
打印方法参数
4.2.6 thread return
代码回滚,回到上一个方法
四、内存断点
4.1 给属性增加断点
watchpoint set variable p1->_name
给p1
对象的name
属性下断点
4.2 通过内存地址设置
watchpoint set expression 内存地址
五、其他指令
5.1 在断点时设置一些默认指令
break command add 组号
5.2 每次stop
时执行一些命令
注意:只对breadpoint,watchpoint
target stop-hook add -o "frame variable"
5.2.1 查看当前所有的stop-hook
target stop-hook list
5.2.2 删除某一组的hook
undisplay 组号
5.3 image
数据越界错误
5.3.1 数组越界错误定位到函数
image lookup -a 0x1bd10580c
5.3.2 快速查看某个类
image lookup -t 类名
网友评论