lldb 常用命令与调试技巧
一、基本介绍
LLDB
是个开源的内置于XCode
的调试工具,它能帮助我们在开发中更快的定位和调试bug
,无论正向和逆向开发中都有很大的作用。lldb对于命令的简称,是头部匹配方式,只要不混淆(不提示歧义),你可以随意简称某个命令。
xcode调试区
下面是xcode debug区域的按钮讲解
二、调试技巧
单步调试
单步调试通常分为两大类,一类为源码级别(source level)
,一类为指令级别(instrution level)
。一行源代码一般需要多行汇编才可以实现,所以当我们越狱开发调试汇编指令单步调试需要用到(instrution level)指令级别。而每一大类又分为step-in和step-over,step-in会进入函数调用,而step-over会跳过函数调用。
1)源码级别(source level)
step-in
以上三条命令是等同的,在有函数调用的位置,会
进入函数内部。
step-over
以上三条命令是等同的,在有函数调用的位置,不会
进入函数内部。
总结
s和n都是跳转到断点的下一行代码位置,区别为,如果下一行代码有函数调用,s会进入函数内部,n则会跳过函数执行。如果没有函数调用则两组命令没有任何区别。
2)指令级别(instruction level)
指令级别的调试,我们需要在xcode的选项卡中设置Debug->Debug Workflow->Always Show Disassembly
,这时候才能看到效果。指令级别的lldb对应的正好是我们点击按钮的同时按下了ctrl键。
step-in
以上两条命令是等同的,在汇编界面,跳转下一步,在有bl
指令的地方,si``会
单步进入到bl
指令所跳转的子函数内部
step-over
以上两条命令是等同的,在汇编界面,跳转下一步,在有bl
指令的地方,ni``不会
单步进入到bl
指令所跳转的子函数内部
step-outsetp out 从一个函数跳出。如果没有执行s或者si,却执行了finish,其实会跳转到汇编指令bl的下一条位置(step out默认是从一个函数跳出,对系统函数调用一定是通过bl执行了函数调用,下一个位置必定为bl的下一个位置)要从嵌套的step out中退出,执行c命令即可跳转到下一个断点。
c
是continue
的简写 表示继续运行s(si)、n(ni)和Xcode调试工具的对应关系如文开始的图
三、lldb常用命令
1.计算表达式命令(expression、po、p)
expression
可简写为expr
计算以及生成一个表达式
创建一个变量并分配值
exp
打印值、修改值
p
、po
与expr
的关系
总结
p
是expr --
的简写,它的工作是把接收到参数在当前环境中进行编译,然后打印出来po
是expr -o --
的简写,它所做的操作和p相同。如果接收到的参数是一个指针,那么它会调用对象的description
方法并打印;如果接收到的参数是一个core foundation
对象,那么它会调用CFShow
方法并打印。如果这两个方法都调用失败,那么po
打印出和p
相同的内容。
使用p做进制转换
2. 内存读取
x
是读取内存的命令,x/4gx
中第一个x
是读取内存命令,后面的g
是每次读取8字节
,x
的意思是16进制显示结果
,4
表示连续打印4段
。
对于
g
,常用的大小格式为b
对应byte 1字节
,h
对应half word 2字节
,w
对应word 4字节
,g
对应giant word 8字节
对于
x
,我们还可以用o
对应8机制
,b
对应2进制
,x
对应16进制
,f
对应浮点
,d
对应10进制
3.call
方法调用
4.变量检查(frame)
我们常用fr v -R
来查看类型的结构
5.检查线程状态
1) 堆栈打印(bt
命令)
bt
是thread backtrace
的简写,如果嫌堆栈打印太长,可以加一个限制,如bt 10
,只打印10行
我们的案例一共只有3行,没达到触发10行限制的条件。
2)thread list
列出当前线程列表
3)thread select
选取某个线程作为后续命令的默认线程
4)frame select
根据下标选择堆栈列表中某帧
此时会跳转到汇编页面,即使没有设置Always Show Disassembly
5)frame info
显示当前帧信息
6)up
移动当前帧(序号加1) down
移动当前帧(序号减1)
可以看到,如果已经是栈顶或者栈底,会提示已在最顶或者最底部。
7)register read
读取寄存器 register write
写入寄存器
8)thread return
跳出当前方法的执行
Debug的时候,也许会因为各种原因,我们不想让代码执行某个方法,或者要直接返回一个想要的值。这时候就该thread return上场了。有返回值的方法里,如:numberOfSectionsInTableView:,直接thread return 20,就可以直接跳过方法执行,返回20.
6.镜像(image)操作
1) image list
镜像列表
这里只截取了部分,因为所有的镜像有几百个,包括了各种动态库
2) image lookup -a
查看崩溃位置
如上所示,我们先得到开始一部分数组越界的崩溃信息,我们找到stack
中4
的位置,可以看到是调用了[person getInt]
,这时候我们使用image lookup -a 地址
就可以找到崩溃位置。image lookup -a
是image lookup --address
的简写
3) image lookup -v -a
查找完整的源代码行信息
同样使用上方数组越界案例
从信息可以看到,我们有三个变量入栈,分别是self
、_cmd
、array
image lookup -v -a
是image lookup -v --address
的简写
4) image lookup -name
查找方法来源
可以看到,所有match到的方法位置信息都给我们了。只不过只有我们自定义的方法给了我们是在main.m:29
5) image lookup -type
查看成员
可以看到,image lookup -type
可以用im loo -t
简写
7.断点(breakpoint)操作
1) b
在某个函数设置一个断点
如代码所示,我们使用b
在getInt
方法中设置了一个断点,执行c
指令继续运行后,代码会断在getInt
方法中第一行b
是以下的简写
br s -n
breakpoint set --name
2) b+文件:行
在某个文件的某行设置一个断点
这种写法是以下命令的简写:
br s -f main.m -l 45
breakpoint set --file main.m --line 45
3) b -[类名 方法名]
、b +[类名 方法名]
设置类中方法的断点
b -[类名 方法名]
是设置实例方法的断点b +[类名 方法名]
是设置类方法的断点
这种写法是以下命令的简写:
breakpoint set -- name -[类名 方法名]
4) breakpoint list
查看断点列表
5) br en 序号
、br dis 序号
启用/禁用断点
在使用br dis 2
后,2号断点就会变灰不可用,br en 2
后,2号断点又会恢复亮色可使用状态
br en 序号
是breakpoint enable 序号
的简写br dis 序号
是breakpoint disable 序号
的简写
6) br del 序号
根据序号移除一个断点
在删除2号断点后,它将立刻在界面上移除。
br del 序号
是breakpoint delete 序号
的简写
Xcode中的断点调试技巧可参考:iOS Xcode Breakpoint(断点)调试
参考链接:
资料推荐
如果你正在跳槽或者正准备跳槽不妨动动小手,添加一下咱们的交流群1012951431来获取一份详细的大厂面试资料为你的跳槽多添一份保障。
评论