iOS LLDB调试

一、简介

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 "[控制器名称 方法名称]"

oc方法设置断点

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:

94个地方

我们点击一下,可以看出第一个断点地方是系统方法,并非是我们自己写的方法
第一个断点的地方

2.8 遍历特定文件中所有方法名为 touchesBegan:withEvent:

breakpoint set --file ViewController.m --selector touchesBegan:withEvent:

特定文件中所有方法名

2.9 遍历整个项目中满足Game:这个字符的所有方法

breakpoint set -r Game:

满足Game:这个字符

2.10 流程控制

2.10.1 继续执行
$c(continue)
2.10.2 单步运行,将子函数当做整体一步执行
$n(next)
2.10.3 单步运行,遇到子函数会进去
$s

三、LLDB代码执行

3.1 查看子控件

expression self.view.subviews

expression

问题1:指令pexpression的关系如何呢?
p

答案:不难看出pexpression的简写形式
简写形式

问题2:指令po又是啥呢?
help expression
help expression

答案:po其实就是调用了OCdescription方法

3.2 ppo的应用

添加数据

四、查看堆栈信息

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->_namep1对象的name属性下断点

给属性增加断点

4.2 通过内存地址设置

watchpoint set expression 内存地址

内存地址

五、其他指令

5.1 在断点时设置一些默认指令

break command add 组号

设置默认指令

5.2 每次stop时执行一些命令

注意:只对breadpoint,watchpoint
target stop-hook add -o "frame variable"

target stop-hook

5.2.1 查看当前所有的stop-hook

target stop-hook list

target stop-hook list

5.2.2 删除某一组的hook

undisplay 组号

undisplay

5.3 image

数据越界错误
5.3.1 数组越界错误定位到函数

image lookup -a 0x1bd10580c

根据堆栈信息找函数

5.3.2 快速查看某个类

image lookup -t 类名

查看类名

你可能感兴趣的:(iOS LLDB调试)