LLDB学习总结

目录

  • 设置断点
  • help
  • expression
  • print & po
  • 流程控制
  • 创建断点
  • watchpoit
  • 总结

LLDB 是一个有着 REPL 的特性和 C++ ,Python 插件的开源调试器。LLDB 绑定在 Xcode 内部,存在于主窗口底部的控制台中。调试器允许你在程序运行的特定时暂停它,你可以查看变量的值,执行自定的指令,并且按照你所认为合适的步骤来操作程序的进展

设置断点

在代码框左侧可以设置断点,当程序执行到断点所在的位置是,程序会停止,这个时候我们可以对程序进行调试。

help

在调试框内我们输入help命令,可以查看可以使用的命令及其简单的描述。

如果希望看到某个命令的用法,可以在调试器内输入help 命令brankpoint为例。

学会使用help命令,可以给我们在调试的过程中提供很多帮助。

expression

LLDB的命令遵循唯一匹配原则:假如根据前n个字母已经能唯一匹配到某个命令,则只写前n个字母等效于写下完整的命令。expressione表示相同的命令。

如果希望修改某个值,可以使用expressione执行语句。在程序运行的中,如果使用e命令改变了某个变量的值,那么在实际运行过程中这个变量也会被修改。(仅在OC中有效,在swift中修改变量的值只在调试期间生效,当继续运行程序时,变量的值实际还是原来的值。)

使用e声明变量时,使用$符号开始作为变量的第一个字符。

expression命令的说有有这样一句话

Important Note: Because this command takes 'raw' input, if you use any
command options you must use ' -- ' between the end of the command options
and the beginning of the raw input.

在使用这个命令的时候需要使用--将实际 command options 和 实际的表达式分开以免造成歧义。

print & po

p

平时使用中这是我们使用最多的两个命令.

print可是使用p代替,实际上它只是expression -- 的别名。

(lldb) e -- self.view
(UIView?) $R0 = 0x00007fa1e2407000 {
  UIKit.UIResponder = {
    ObjectiveC.NSObject = {}
  }
}
(lldb) p self.view
(UIView?) $R1 = 0x00007fa1e2407000 {
  UIKit.UIResponder = {
    ObjectiveC.NSObject = {}
  }
}

上面两个代码效果完全相同。

在swift中如果使用let声明一个变量,使用lldb不能打印这个变量,如果你试图打印这个变量,将会得到下面的提示,因为编译器认为你不会再改变这个变量,所以即使修改optimization level 为 NONE也不能打印,如果你希望打印这个变量可以将这个变量用var声明。

error: <EXPR>:3:1: error: use of unresolved identifier 'even1'
even1
^~~~~

po

在OC和swift中所有的对象都是用指针代表的(除了某些特殊的对象,这里不做讨论),使用p打印出来的都是对象的指针,而不是对象的本身,如果我们想要打印对象,可以使用po(它实际上是expression -O --的别名)。po打印的内容在OC和swift中是有区别的。

在OC中这样打印出来的是当前对象的description方法的返回值,如果没有实现回到父类中寻找,知道找到NSObject中,但是-[NSObject description]返回实际上也是对象的指针,和使用p并没有区别,所有对自定义的类,我们可以实现description方法来方便我们调试。

在swift中,对遵守CustomDebugStringConvertible协议的类或结构体,使用po可以自定义打印内容。

流程控制

当程序到达断点的时候程序就会暂停,在调试条上面会出现4个可以控制流程的按钮

  1. continue 按钮,继续执行直到下一个断点,在LLDB中使用process continue,continue,c都能有相同的作用。
  2. step over 按钮, 会以黑盒的方式执行一行代码。如果所在这行代码是一个函数调用,那么就不会跳进这个函数,而是会执行这个函数,然后继续。LLDB 则可以使用 thread step-overnext,或者 n 命令。
  3. step in 按钮, 如果当前行是函数,则会进入函数内部,如果不是,则和step over作用相同,LLDB 则可以使用 thread step instep,或者 s 命令。
  4. step out 按钮,如果你曾经不小心跳进一个函数,但实际上你想跳过它,常见的反应是重复的运行 n 直到函数返回。其实这种情况,step out 按钮是你的救世主。它会继续执行到下一个返回语句 (直到一个堆栈帧结束) 然后再次停止。

Thread Return

调试时,还有一个很棒的函数可以用来控制程序流程:thread return 。它有一个可选参数,在执行时它会把可选参数加载进返回寄存器里,然后立刻执行返回命令,跳出当前栈帧。这意味这函数剩余的部分不会被执行。这会给 ARC 的引用计数造成一些问题,或者会使函数内的清理部分失效。但是在函数的开头执行这个命令,是个非常好的隔离这个函数,伪造返回值的方式 。

创建断点

断点是一个非常强大的功能,在XCcode左侧有一个管理断点的面板,在这里可以看到所有的断点,并且可以管理,编辑和为断点添加行为。

1529650655865.jpg

编辑断点

选中断点右键点击断点,出现下面断点

1. condition:指定当满足条件时断点才会生效

来看一个例子,在Condition中设置一个 i == 5

代码如下

override func viewDidLoad() {
    super.viewDidLoad()
    var i = 5
    // 在这里设置断点 
}

这个时候代码执行到这里时会暂停,如果修改代码var i = 6则断点不会停下。

2. Ignore:忽略前N次

上面断点设置Ignore为3,在控制台中会打印

0
1
2
(lldb) 

然后程序暂停。

3.Action

上面的例子中,你或许想知道每一次到达断点的时候 i 的值。我们可以使用 p i 作为断点行为。这样每次到达断点的时候,都会自动运行这个命令。

20180622151948.png

4.赋值后继续运行

看编辑断点弹出窗口的底部,你还会看到一个选项: "Automatically continue after evaluation actions." 。它仅仅是一个选择框,但是却很强大。选中它,调试器会运行你所有的命令,然后继续运行。看起来就像没有执行任何断点一样 (除非断点太多,运行需要一段时间,拖慢了你的程序)。

watchpoit

使用lldb也可以实现变量的监听。当我们关心某个类实例变量何时被修改,如果使用属性修改实例变量的值时,我们可以在setter方法中打断点或者直接在属性上面打上断点,都能够监听变量改变,但是有时候直接通过修改实例变量修改,不会调用setter方法。

那么如何监听这个实例变量被改变了呢,我们可以通过监视这个实例变量的地址的写入。

下面示例代码:

class Person {
    
    var name: String!
    
}

如果希望监听Person实例变量name的改变

    let person = Person()
    // 在这里打上断点
    person.name = "john"
    
    person.name = "toms"

控制台

(lldb) watchpoint set variable -s 8 -- person.name
Watchpoint created: Watchpoint 1: addr = 0x6000004468b0 size = 8 state = enabled type = w
    declare @ '/Users/blade/Desktop/LLDBTest/LLDBTest/ViewController.swift:26'
    watchpoint spec = 'person.name'
    new value: ""

person.name的值被修改的时候会程序会暂停,但是我在试验的遇到一个问题,第一次修改的时候new value总是空的,我也不知道是为什么。

// 监听属性修改时,控制台打印
Watchpoint 1 hit:
old value: ""
new value: ""

Watchpoint 1 hit:
old value: ""
new value: "toms"

注意在OC中需要通过watchpoint set variable -s 8 -- person->_name这种方式去监听变量的变化。

总结

lldb是非常强大的,如果掌握的这些方法,能够极大提高解决bug的效率。

引用

lldb error: variable not available

与调试器共舞 - LLDB 的华尔兹

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

推荐阅读更多精彩内容

  • 转载 与调试器共舞 - LLDB 的华尔兹: https://objccn.io/issue-19-2/ 推荐:i...
    F麦子阅读 3,325评论 0 10
  • Xcode的使用中总是离不开调试这个环境,在一年多的iOS开发时间中,我更多地依赖于XCode本身提供的GUI工具...
    王小明if阅读 17,535评论 8 94
  • 你是否曾经苦恼于理解你的代码,而去尝试打印一个变量的值? NSLog(@"%@", whatIsInsideThi...
    我是啊梁阅读 801评论 1 1
  • 你是否曾经苦恼于理解你的代码,而去尝试打印一个变量的值? NSLog(@"%@", whatIsInsideThi...
    木易林1阅读 954评论 0 4
  • 与调试器共舞 - LLDB 的华尔兹 nangege 2014/12/19 你是否曾经苦恼于理解你的代码,而去尝试...
    McDan阅读 881评论 0 0