iOS 开发调试利器 - LLDB命令

请叫我序猿.jpg

lldb的Xcode默认的调试器,它与LLVM编译器一起,带给我们更丰富的流程控制和数据检测的调试功能。平时用Xcode运行程序,实际走的都是lldb。熟练使用lldb,可以让你debug事半功倍

  • lldb 用法
    首先在应用程序内打断点。
    接下来一个一个的去介绍和使用。

  • apropos :调试器命令列表相关的词或主题
    语法:apropos <search-word>
    作用:输出你想要搜索的关键词的相关内容。
    例子:apropos log
    结果:

    apropos.png
  • breakpoint :命令操作断点
    语法:breakpoint <subcommand> [<command-options>]
    作用:可以通过命令来对断点进行增加、删除等操作。
    一些子命令如下:
    1、clear:删除或禁用断点匹配指定的源文件和行。
    2、command:命令添加,删除和清单LLDB命令在遇到断点时执行。
    3、delete:删除指定的断点(s)。如果没有断点指定,删除它们。
    4、disable:禁用指定断点(s),而不删除它们。如果没有指定,禁用所有断点。
    5、enable:使指定的禁用断点(s)。如果没有断点指定,使所有的人。
    6、list:列举一些或所有断点配置的详细级别。
    7、modify:修改选项断点或设置的断点可执行文件。如果没有指定断点,作用于最后创建断点。
    8、name:命令来管理断点的名字标签
    9、set:设置一个断点或设置断点的可执行文件。
    例子:通过 breakpoint 来添加、删除以及查找断点。

查看当前断点列表

  ![查看当前断点列表.png](http://upload-images.jianshu.io/upload_images/1622166-558a9f2f240b583c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

红色框框里面表示断点的行数。可以看出来现在也就只有2个断点,一个在73行,一个在80行。
- 添加一个95行的断点
breakpoint set -f ViewController.m -l 95
-f 后面的是文件名 -l 后面是行数
- 再次查看当前断点列表

  ![再次查看断点列表.png](http://upload-images.jianshu.io/upload_images/1622166-5fe514ad42966a48.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
- 删除 80 行的断点
      breakpoint clear -f ViewController.m -l 80
- 结果列表中就没有 80 行的断点信息了。
![最后的断点列表.png](http://upload-images.jianshu.io/upload_images/1622166-790ba6f138a700a7.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
  • bugreport :命令来创建特定于域的bug报告
    语法:bugreport <subcommand> [<subcommand-options>]
    作用:创建一份 bug 报告
    例子:
    bug report unwind XXX(XXX 是你想看的方法名)
    结果会输出一堆东西。you can try!

  • command :管理自定义命令LLDB命令(创建别名)
    语法:command <subcommand> [<subcommand-options>]
    一些子命令:
    1、alias:定义一个自定义命令
    2、delete:删除一个或多个自定义命令的命令
    3、history:当前执行的历史命令
    4、regex:定义一个现有命令的自定义命令
    5、script:来管理自定义命令实现的脚本解释器
    6、source:从文件读取和执行命令LLDB
    7、unalias:删除一个或多个自定义命令定义为“命令别名”
    例子:
    想知道你执行 LLDB 几条命令,输入
    command history
    还有个实用的例子:
    比如上面的添加断点命令过长,那么我们可以这样做。
    command alias bkt breakpoint set -f %1 -l %2
    然后再添加断点。
    bkt ViewController.m 90
    你看结果会发现已经添加上了,是不是很方便?


    别名添加断点.png

    如果不想要这个别名了就可以执行下列命令把它给删除。
    command unaries but

  • disassemble :拆卸指定的指令
    语法:disassemble [<cmd-options>]
    例子:
    disassemble -b
    这样会显示你当前断点所在的方法内所有的操作码字节。
    效果:


    操作码字节.png

    红色框内的信息能更好的帮助你调试程序。
    如果你想拆卸某一行可以用下面的命令:
    disassemble -c 84(这个数字就是你想要拆卸的行数,当然了他会联系上下文给你拆卸这个对象的信息)

  • expression (我用到的: 修改程序中的代码)
    场景:假设你程序运行后发现有个视图的背景颜色不好看,需要改,好吧,在代码中改一下,再运行。发现不好看,再改。这样太过麻烦,但是我们可以用 expression 来实现,代码:
    expression imageView.backgroundColor = [UIColor redColor]
    然后再运行你就会发现这个视图的颜色变成红色了。不止颜色,一些数值也是可以改的。

  • frame 命令选择与当前线程的堆栈帧
    子命令:
    1、info:列表当前堆栈帧在当前的信息线程
    2、select:选择当前堆栈框架内通过索引当前线程
    3、variable:显示变量当前堆栈帧。默认为所有参数和局部变量的范围
    效果:


    frame效果图.png

    1中,箭头表示的是你断点所在的位置
    后面的就是你所写的代码
    2中,有你当前所在的类的名字,所在方法的方法名以及一些创建的对象
    3中,就是列举方法名,行数,类名等信息。
    根据自己的喜好选择相应的命令。

  • quit 退出当前的LLDB。

  • register 访问当前线程的寄存器和堆栈帧
    子命令:
    1、read:读取当前的寄存器值当前帧
    2、write:修改一个寄存器值

  • settings 管理 LLDB 的设置
    子命令:
    1、append:将值附加到调试器里面。数组、字典或者字符串设置。
    2、clear:清除调试器
    3、insert-after:在指定的元素的索引,将一个或多个值插入一系列调试器设置
    4、insert-before:在指定的元素的索引,立刻将一个或多个值插入一系列调试器设置
    5、list:调试器列表
    6、remove:移除设置
    7、replace:替换设置中的值
    8、set:设置指定的调试器的设置值
    9、show:显示调试器设置和他们目前的值。

  • source 检查源代码所描述的调试信息当前目标的过程
    子命令:
    1、info:显示一行信息来源为当前目标的过程。默认为当前堆栈帧中指令指针
    2、list:显示指定的当前目标过程的源代码

  • thread 操作在一个或多个线程在当前过程
    子命令:
    1、backtrace:显示线程调用堆栈。默认为当前可以指定线程,线程索引作为参数。使用thread-index看到所有线程。
    2、continue:继续执行当前目标的过程。
    3、info:显示一个扩展的总结一个或多个线程。
    4、jump:将程序计数器设置为一个新的地址。
    5、list:显示每个线程在当前目标的总结的过程。
    6、plan:管理线程控制计划执行。
    7、return:返回从堆栈帧,短路执行更新的框架和选择屈服指定的值。
    8、select:更改当前选中的线程。
    9、step-in:进入调用
    10、step-init:单步调用
    11、step-ints-over:单步,跨过调用。
    12、step-out:执行完当前堆栈帧并停止之后返回。
    13、step-over:单步,跨过调用。
    14、step-scripted:C中选择的脚本类。
    15、until:到达到行号或地址当前或指定的线程,停止时返回从当前函数作为一种安全措施。
    例子:
    thread info


    当前线程的信息.png
  • type 命令操作的类型系统
    子命令:

    • 1️⃣、category:操作类型分类
      • define:定义一个新的类别
      • delete:删除一个类别
      • disable:禁用一个类别
      • enable:启用一个类别
      • list:现有的类别的列表
    • 2️⃣、filter:操作类型过滤器
      • add:添加一个新的过滤器的类型
      • clear:删除所有现有的过滤器
      • delete:删除现有的滤波器类型
      • list:显示当前过滤器的列表
    • 3️⃣、format:自定义值显示格式
      • add:添加一个新的格式类型
      • clear:删除所有现有的格式样式
      • delete:删除现有的格式风格类型
      • info:评估提供的表达式和显示格式应用于结果值
      • list:显示当前的列表格式
    • 4️⃣、lookup:当前查找类型和声明
    • 5️⃣、summary:编辑变量汇总
      • add:添加一个新的汇总的风格类型
      • clear:删除所有现有的总结
      • delete:删除现有的一种总结类型
      • info:评估提供的表达式和显示总结应用结果值
      • list:显示当前的列表格式
    • 6️⃣、synthetic:操作合成类型
      • add:添加一个新类型合成提供者
      • clear:删除所有的类型
      • delete:删除现有的一种合成类型
      • info:评估提供的表达式和显示总结应用结果值
      • list:显示当前的列表格式
  • version 显示调试器LLDB版本

  • watchpoint 操作检查点,检查内存的读写。

    • 1️⃣、command:添加,删除和检查LLDB命令当监视点
      • add:添加一组命令LLDB监视点
      • delete:删除监视点
      • list:监视点成功的列表
    • 2️⃣、delete:删除指定的监视点
    • 3️⃣、disable:禁用指定的监视点,而不删除它
    • 4️⃣、enable:使指定的禁用的监视点
    • 5️⃣、ignore:设置忽略依靠指定的监视点
    • 6️⃣、list:列出所有监测点配置的表
    • 7️⃣、modify:在监视点或者设置监测点上修改可执行文件,如果没有指定监视点,就传递一个空参数做修改。
    • 8️⃣、set:设置监视点
      例子:
      创建一个监视点
      watchpoint set expression -- a(这个a 在代码中是 int a = 0;)
      会输出这样的信息
      Watchpoint created: Watchpoint 1: addr = 0x00000000 size = 8 state = enabled type = w
      分别为:监视点的代号,内存地址,大小,状态和类型。
      再添加个对这个 a 的读写检测
      watchpoint set variable -w read_write a
      则会输出
Watchpoint created: Watchpoint 3: addr = 0x7fff54ed67c4 size = 4 state = enabled type = rw
    declare @ '/Users/XXX/Desktop/Demozz/Demozz/ViewController.m:89'
    watchpoint spec = 'a'
    new value: 0

比上面的输出相比,多了以下几点改变
1、监视点的代号、内存地址、大小、类型都变了。
2、增加了declare(状态声明)
3、增加了监视点的规范
4、增加了输出这个检查的变量的值。
那我们打印一些监视点的列表
watchpoint list
则输出

Number of supported hardware watchpoints: 4
Current watchpoints:
Watchpoint 1: addr = 0x00000000 size = 8 state = enabled type = w
Watchpoint 3: addr = 0x7fff54ed67c4 size = 4 state = enabled type = rw
    declare @ '/Users/miya-shaocong/Desktop/Demozz/Demozz/ViewController.m:89'
    watchpoint spec = 'a'
    new value: 0

如果我们想删除一个监视点,只需要把代号给提交过去就好了。
watchpoint delete 1
想删除全部的话,就这样
watchpoint delete
它会让你确认
About to delete all watchpoints, do you want to do that?: [Y/n]
然后你输入 Y 确定就好了。

  • po 显示任何返回值与控制的格式类型
    • 变量
      比如你想看某个变量的值,不需要在代码中添加log,直接断点到那个地方,然后 po 变量名,就会输出你想要看到值
(lldb) po b
100
  • 坐标
    比如你想看到某个视图的坐标以及大小信息,那就直接 po 这个视图的frame。
(lldb) po self.view.frame
(origin = (x = 0, y = 0), size = (width = 375, height = 667))

你还可以尝试输出其他(你想要看的东西)。

  • print 更详细的输出,(包括类型)
(lldb) print a
(int) $5 = 0
(lldb) print b
(int) $6 = 100
(lldb) print self.view
(UIView *) $7 = 0x00007fd183d04cf0
(lldb) print self.view.frame
(CGRect) $8 = (origin = (x = 0, y = 0), size = (width = 375, height = 667))

$X 这种是命令结果的引用名,我们可以用于任何其他表达式或者接收参数的命令。
比如:

(lldb) print $5 + 109
(int) $9 = 109
// ---
(lldb) po $8
(origin = (x = 0, y = 0), size = (width = 375, height = 667))
  • next 直接跨过当前的断点,跳到下一个断点位置,并输出断点所在的行数。
  • run 重新启动程序。
  • kill 终止当前的程序
  • 可视化工具操作
    第一步:右键断点,然后选择Edit Breakponit
    第二步:


    Xcode可视化工具.png

    第三步:运行到断点看结果


    结果.png

好了,我要分享的关于 LLDB 的命令就到这里了,如果想要学习其他的命令,可以通过 help 来自己学习。如果您觉得这篇文章对你有用,能否给个喜欢?

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

推荐阅读更多精彩内容

  • 前言 LLDB是个开源的内置于XCode的具有REPL(read-eval-print-loop)特征的Debug...
    Noskthing阅读 18,355评论 10 89
  • [转]浅谈LLDB调试器文章来源于:http://www.cocoachina.com/ios/20150126/...
    loveobjc阅读 2,410评论 2 6
  • 转载 与调试器共舞 - LLDB 的华尔兹: https://objccn.io/issue-19-2/ 推荐:i...
    F麦子阅读 3,281评论 0 10
  • 随着Xcode 5的发布,LLDB调试器已经取代了GDB,成为了Xcode工程中默认的调试器。它与LLVM编译器一...
    随风飘荡的小逗逼阅读 1,344评论 0 0
  • 江歌刘鑫事件,具体内容不说了,网络这么发达,随便一百度就有了。就算不百度,公众号上也都在发发发,发到连我这种不关心...
    李户勒大阅读 349评论 0 1