值得持续学习的LLDB技巧

一、概述

开发调试中,常常使用LLDB加快调试,更快速简单的定位到问题点。
下面是之前收集并且整理的常用命令 、插件和 使用技巧。

二、命令

关于命令的详细用法,使用help <command> <subcommand>进行查看

2.0、关于~/.lldbinit

LLDB有了一个启动时加载的文件~/.lldbinit,每次启动都会加载。
可以添加一些自定义命令,加载插件等等。

cat ~/.lldbinit查看文件内容,包含以下信息:

  • command script import /path/to/fblldb.py
    一般系统,在~/.lldbinit默认导入facebook的fblldb.py里面命令。
    当然也可以自行安装相关插件。

  • @import 导入第三方框架,可以把基础框架放入到~/.lldbinit文件中
    例如 @import Foundation/UIKit/CoreGraphics 等系统框架,否则lldb调试相关框架会报错,

2.1、打印命令

  • p 打印基础数据类型;打印对象时会返回对象指针地址。
    p/x 变量名 打印变量的16进制(x 代表十六进制格式、t 代表二进制格式)
    p/t:二进制输出
    p/c:字符编码
    p/x:16进制输出

  • 查看对象内存分配
    x 对象:对象内存情况
    x/4gx 对象:按照四段16字节输出对象内存情况
    x/8gx 对象:按照八段16字节

  • po 打印对象的desc信息

  • frame variable 打印

  • exp 命令作用同p命令

2.2、堆栈

  • bt 打印当前线程堆栈(backtrace的缩写)
    bt all 打印所有线程的堆栈

  • frame select 层数 跳转到某一层的堆栈
    frame variable 查看当前堆栈的变量

  • up 向上查看堆栈

  • down 向下查看堆栈

2.3、线程

  • thread list 列出所有的线程
  • thread select 线程编号 切换线程
  • thread backtrace
  • thread backtrace all 打印所有线程的堆栈
  • thread return 各种原因,不想让代码执行某个方法,或者要直接返回一个想要的值。

2.4、表达式

  • e、expr、expression 执行表达式,常用的做法是,在不重新编译的情况下,给变量赋值。
    self.view.backgroundColor = [UIColor redColor];

2.5、关于imageimage是LLDB给 target modules 取的别名 )

  • image list 列出当前执行的和依赖第三方的所有镜像

  • image lookup -n 名字 查找项目中某个变量名、函数名等,包括第三方SDK或者静态库。
    例如,用来查找同名的Category方法。

  • image lookup --address 地址+偏移量 等价于 image lookup -a 地址+偏移量
    image lookup -v -a 地址+偏移量 查找完整的源代码行信息

  • image lookup -type 类名 查看类的成员

2.6、断点

调试技巧:断点编辑,xcode中可以右键某个断点,可以进行断点编辑,可以设置某种条件下触发断点,实际开发中蛮实用。

2.6.1、breakpoint set 断点设置,其中breakpoint可以缩写为b
  • -n 方法名 根据方法名给当前类设置断点。
    也可以根据方法名给指定类多个方法设置断点,如下
    breakpoint set -n "-[ViewController save:]" -n "-[ViewController continueGame:]" -n "-[ViewController pauseGame:]"

  • breakpoint set --selector 方法名 给整个项目某个指定方法设置断点

  • -f 指定文件设定
    breakpoint set -f ViewController.m -n viewDidAppear:

  • -l 指定某一行设置断点
    breakpoint set -f ViewController.m -l 33

  • -a 给某个内存地址设置断点

  • -c 设置条件断点
    breadpoint set -n helloworld: -c flag==NO

  • -r 遍历整个项目中的所有方法,设置断点
    例如breakpoint set -r Game: 为项目所有包含 Game: 这个字符的所有方法,设置断点

2.6.2、breakpoint command 给断点设置一些命令
  • breakpoint command add 添加命令
    例如,breakpoint command add -o "po self.view" 3
    其中,-o完整写法是–one-liner,表示增加一条命令。3表示对id为3的breakpoint增加命令。

  • breakpoint command list num 查看某个断点的所有命令

  • breakpoint command delete num 删除某个断点的所有命令

2.6.3、其他
  • breakpoint list 查看断点列表
  • breakpoint disable/enable num 开启和禁止断点
  • breakpoint delete num 删除某个断点,没有入参则删除所有断点

2.7、watchpoint 内存断点

如果说breakpoint是对方法生效的断点,watchpoint就是对地址生效的断点。
想要知道某个属性什么时候被篡改了,我们该怎么办呢?就可以使用watchpoint。

2.7.1、设置
  • watchpoint set variable 设置变量
    例如,watchpoint set variable self->name
    不接受方法,因此以下命令无效watchpoint set variable self.name ,因为OC中点操作符调用setter和getter方法。

  • watchpoint set expression address 观察某个地址

2.7.2、命令
  • watchpoint command add\delete\list 同breakpoint,断点设置命令
2.7.3、其他
  • watchpoint list 查看当前所有
  • watchpoint enable/disable num 开启和禁止断点
  • watchpoint delete num

2.8、流程控制语句

  • c 继续,continue
  • n next
  • s 进入step in
  • finish 完成

2.9、targets

2.9.1、modules
  • target modules lookup 访问一个或多个目标模块的信息
    由于LLDB给target modules取了个别名image,所以这个命令我们又可以写成image lookup。 如下
    详见上面的image命令
2.9.2、stop-hook

breadpointwatchpoint 断点停止的时候,去执行一些命令。

  • target stop-hook list 查看所有的hook

  • target stop-hook add 添加的hook
    使用-o表示添加一条命令。

  • target stop-hook delete num 删除指定编号的hook,没有入参num则表达式全部

  • target stop-hook disable/enable num 开启和禁用hook,没有入参num则代表全部

2.9.3、target symbols add(add-dsym)

当我们对接framework的时候,如果只有framework代码,没有工程代码,能不能debug呢?其实我们只需要拿到工程的ipa和dSYM文件,就可以debug了,通过Attach to Process,使用命令add-dsym将dSYM文件加入target,即可只debug framework,不需要工程的代码

2.10、其他

  • call 调用方法,不打印值;p、po也有该功能,并且会打印返回值

  • disassemble,缩写为dis 打印当前目标的汇编代码

使用例子demo
1、image list
读取app的image进程内存首地址

[  0] 67EC1881-E7CC-38BC-A49E-D6FE5E755FB0 0x000000010ebe1000

2、memory read addr
addr-符号表的符号地址,可以通过mach-o查看。

1.png

addr = 第一步首地址 + mach-o的offset地址
0x10EBE9050 = 0x000000010ebe1000 + 0x00008048

2.png

  • 相关内存命令:find、history、read、region、writer

3、dis -s addr
这一步的addr是上一步红框的倒叙(由于iOS是小端模式,内存地址8位倒着读)。

3.png

输出:HelloWorld/fxNSlog:,其中 fxNSlog: 是用fishhook NSLog的替换函数。

4、操作寄存器
register read/write

三、LLDB 和 Python

3.1、插件的原理

LLDB 有内建的,完整的 Python 支持。在LLDB中输入 script,会打开一个 Python REPL。

3.2、Chisel插件(facebook开源调试利器,原理同时)

GitHub地址

常用的命令:
  • pviews self.view 递归打印所有的view,并能标示层级

  • pvc 递归打印当前ViewController的层级

  • visualize img_obj 使用Mac的预览打开一个 UIImage, CGImageRef, UIView, 或 CALayer。

  • fv & fvc var
    通过类名搜索当前内存中存在的view和viewController实例的命令,支持正则搜索。

  • show/hide 无需重新编译,直接显示和隐藏view或者layer

  • caflush 重新渲染绘制界面,相当于执行了 [CATransaction flush] 方法
    注意如果在动画过程中执行这个命令,就直接渲染出动画结束的效果。
    在调试界面颜色、坐标之类的时候,可以直接在控制台修改属性,然后caflush就可以看到效果啦。

  • mask/umask 和 border/unborder
    这两组命令用来标识一个view或layer的位置时用。
    mask用来在view上覆盖一个半透明的矩形, border可以给view添加边框。

  • presponder self.view 打印响应者链

** 更多好用的用法,请参考help命令,值得你深入研究。 **

四、XCode调试

  • 显示汇编相关,Debug -> Debug Wokflow -> Always Show Disassembly 则会显示汇编信息。
    例子:在NSLog打断点,如下
NSString *str = @"helloworld";
id __weak objc = str;
NSLog(@"%@", objc);
image.png

参考

LLDB调试小节
objc.io#19#与调试器共舞 - LLDB 的华尔兹
iOS中教你快速掌握LLDB调试技巧
Chisel-LLDB命令插件,让调试更Easy

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
禁止转载,如需转载请通过简信或评论联系作者。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,542评论 6 504
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,822评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,912评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,449评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,500评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,370评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,193评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,074评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,505评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,722评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,841评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,569评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,168评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,783评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,918评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,962评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,781评论 2 354

推荐阅读更多精彩内容