原创Blog,转载请注明出处
http://blog.csdn.net/hello_hwc?viewmode=list
我的stackoverflow


前言:LLDB是个开源的调试器,与XCode绑定的

LLDB的使用中,Swift与Objective C还是有一些差别的

本文主要侧重LLDB的常用命令


资料(目前状态XCode 7.2 Swift 2.1.1),非XCode 7.2+本文代码可能不能运行

  • objc.io(强烈建议有Objective C经验,但是对LLDB不熟悉的深入研究下)
  • Apple官方文档
  • LLDB的文档
  • 一个封装LLDB的库,可以辅助调试
  • 2015 WWDC视频

对了,Swift到现在也不过一岁半,所以LLDB对于Swift的支持肯定不如OC那么好。


如何打开LLDB如何使用?

通常的方式就是断点,另外,关于利用XCode图形化调试,在我这篇文章里有详细讲解

本文适合XCode 7.2 +
不管是在程序中加断点

还是手动的暂停程序


让代码停在Swift Error 或者Objective C异常

停在Objective C异常

(lldb) br s -E  objc
Breakpoint 6: where = libobjc.A.dylib`objc_exception_throw, address = 0x000000010dededbb

停在Swift Error

(lldb) br s -E swift
Breakpoint 7: where = libswiftCore.dylib`swift_willThrow, address = 0x000000010e55ccc0

停在某一种类型的Swift Error

(lldb) br s -E swift -O EnumError
Breakpoint 8: where = libswiftCore.dylib`swift_willThrow, address = 0x000000010e55ccc0

以此作为开端,希望读者能耐心看完,本文很长


准备工作

为了方便,我们先写好这样的一个Model类,定义个ErrorType,并且定义个实例方法抛出异常

enum CustomError:ErrorType{case LeoError1case LeoError2
}
class Person:NSObject{var name:Stringvar age:UInt32init(name:String,age:UInt32){self.name = nameself.age = age}//重写description是为了方便调试override var description:String{return "name:\(name) age:\(age)"}func PersonException() throws{throw CustomError.LeoError1}
}

然后在viewDidLoad中初始化一个对象,并打一个断点

let person = Person(name: "Leo", age: 23)

打印命令 p/po

p

(lldb) p person
(SwiftLLDBDemo.Person) $R0 = 0x00007f99b8d30b40 {ObjectiveC.NSObject = {isa = SwiftLLDBDemo.Person}name = "Leo"age = 23
}

po

(lldb) po person
name:Leo age:23

p命令会打印出对象的类型,如果是Objective C对象,会打印出isa,以及属性的值
po 命令 对于继承自NSObject得对象,指示会打印出description中的内容

再举个例子

(lldb) po ["123","345"]
▿ 2 elements- [0] : "123"- [1] : "345"(lldb) p ["123","345"]
([String]) $R2 = 2 values {[0] = "123"[1] = "345"
}

也可以,调用一段代码

(lldb) p for i in 1...3{ print(i) }
1
2
3

执行代码 e

expression命令可以帮助我们执行代码,

(lldb) e person.name = "Jack"
(lldb) p person
(SwiftLLDBDemo.Person) $R1 = 0x00007f9bf1424c20 {ObjectiveC.NSObject = {isa = SwiftLLDBDemo.Person}name = "Jack"age = 23
}

在这我们深入的研究所有命令

(lldb) help

内容太多,不拷贝进来了,自己在XCode里敲敲试试吧。

可以看到,有一部分是alias部分,有linux经验的同学应该知道,alias就是将一个简单的命令设置为复杂命令的别名。我们上面讲到的两个命令p/po就是两个alias命令

  p         -- ('expression --')  Evaluate an expression (ObjC++ or Swift) inthe current program context, using user defined variables andvariables currently in scope.po        -- ('expression -O  -- ')  Evaluate an expression (ObjC++ or Swift)in the current program context, using user defined variables andvariables currently in scope.

所以,p命令,本质是expression -- ;po命令,本质是expression -O --

(lldb) expression -- person
(SwiftLLDBDemo.Person) $R0 = 0x00007f96a3f792d0 {ObjectiveC.NSObject = {isa = SwiftLLDBDemo.Person}name = "Leo"age = 23
}
(lldb) expression -O -- person
name:Leo age:23

更加复杂的执行

例如,动态的修改view的背景色

e self.view.backgroundColor = UIColor.blueColor

Expression命令很灵活

格式化打印 -f (format)

(lldb) expr -f bin -- person.age
(UInt32) $R2 = 0b00000000000000000000000000010111
(lldb) expr -f oct -- person.age
(UInt32) $R3 = 027
(lldb) expr -f hex -- person.age
(UInt32) $R4 = 0x00000017

格式化打印可以更简单

(lldb) p/x person.age
(UInt32) $R5 = 0x00000017

打印Raw value expr -R -- 变量

(lldb) expr -R -- person
(SwiftLLDBDemo.Person) $R6 = 0x00007f96a3f792d0 {ObjectiveC.NSObject = {}name = {_core = {_baseAddress = {_rawValue = 0x0000000101041298 "Leo"}_countAndFlags = {value = 3}_owner = None {Some = {instance_type = 0x0000000000000000}}}}age = {value = 23}
}

显示变量类型expr -T -- 变量

(lldb) expr -T -- person
(SwiftLLDBDemo.Person) $R7 = 0x00007f96a3f792d0 {(NSObject) ObjectiveC.NSObject = {(Class) isa = SwiftLLDBDemo.Person}(String) name = "Leo"(UInt32) age = 23
}

当然也可以结合多个使用expr -RRT -- person

帮助命令,可以再深入看看其他执行选项,不过不是很常用

 help expression

LLDB变量

LLDB的变量和脚本语言类似,以美元符号开头,使用的时候也要带着美元符号,调用的时候和Swift的语法一致
例如

(lldb) e var $a = 10
(lldb) p $a
(Int) $a = 10(lldb) e var $b = Person(name: "Jack", age: 25)
(lldb) p $b
(SWTest.Person) $b = 0x00007f8909539080 {ObjectiveC.NSObject = {isa = SWTest.Person}name = "Jack"age = 25
}

断点

断点采用这个命令breakpoint,缩写br
断点命令的文档较少,这里先列出文档

(lldb) help breakpoint
The following subcommands are supported:clear   -- Clears a breakpoint or set of breakpoints in the executable.command -- A set of commands for adding, removing and examining bits ofcode to be executed when the breakpoint is hit (breakpoint'commands').delete  -- Delete the specified breakpoint(s).  If no breakpoints arespecified, delete them all.disable -- Disable the specified breakpoint(s) without removing them.  Ifnone are specified, disable all breakpoints.enable  -- Enable the specified disabled breakpoint(s). If no breakpointsare specified, enable all of them.list    -- List some or all breakpoints at configurable levels of detail.modify  -- Modify the options on a breakpoint or set of breakpoints inthe executable.  If no breakpoint is specified, acts on thelast created breakpoint.  With the exception of -e, -d and -i,passing an empty argument clears the modification.name    -- A set of commands to manage name tags for breakpointsset     -- Sets a breakpoint or set of breakpoints in the executable.

breakpoint set -E language
breakpoint s -E swift -O ErrorType

列出断点

(lldb) br li
Current breakpoints:
1: file = '/Users/huangwenchen/Desktop/SWTest/SWTest/ViewController.swift', line = 27, locations = 1, resolved = 1, hit count = 11.1: where = SWTest`SWTest.ViewController.viewDidLoad (SWTest.ViewController)() -> () + 75 at ViewController.swift:27, address = 0x000000010ef8556b, resolved, hit count = 1 

禁用断点

(lldb) br dis 1
1 breakpoints disabled.

删除断点

(lldb) br del 1
1 breakpoints deleted; 0 breakpoint locations disabled.
(lldb) br li
No breakpoints currently set.

添加断点

(lldb) br set -f ViewController.swift -l 28
Breakpoint 2: where = SWTest`SWTest.ViewController.viewDidLoad (SWTest.ViewController)() -> () + 139 at ViewController.swift:29, address = 0x000000010ef855ab

也可以简写为

(lldb) b ViewController.swift:28
Breakpoint 3: where = SWTest`SWTest.ViewController.viewDidLoad (SWTest.ViewController)() -> () + 139 at ViewController.swift:29, address = 0x000000010ef855ab
(lldb) br li
Current breakpoints:
2: file = 'ViewController.swift', line = 28, locations = 1, resolved = 1, hit count = 02.1: where = SWTest`SWTest.ViewController.viewDidLoad (SWTest.ViewController)() -> () + 139 at ViewController.swift:29, address = 0x000000010ef855ab, resolved, hit count = 0 3: file = 'ViewController.swift', line = 28, locations = 1, resolved = 1, hit count = 03.1: where = SWTest`SWTest.ViewController.viewDidLoad (SWTest.ViewController)() -> () + 139 at ViewController.swift:29, address = 0x000000010ef855ab, resolved, hit count = 0 

断点Name

断点名称是用来管理一组断点的,通过name可以启用或者禁用一组断点,一个断点可以有多个name,很像tag。

br set -f ViewController.swift -l 28 -N leo
(lldb) br set -f ViewController.swift -l 28 -N leo
Breakpoint 2: 3 locations.
(lldb) br li
Current breakpoints:
1: file = '/Users/huangwenchen/Desktop/SWTest/SWTest/ViewController.swift', line = 34, locations = 1, resolved = 1, hit count = 11.1: where = SWTest`SWTest.ViewController.viewDidLoad (SWTest.ViewController)() -> () + 75 at ViewController.swift:34, address = 0x00000001070d51fb, resolved, hit count = 1 2: file = 'ViewController.swift', line = 28, locations = 3, resolved = 3, hit count = 0Names:leo2.1: where = SWTest`SWTest.ViewController.__deallocating_deinit + 12 at ViewController.swift, address = 0x00000001070d538c, resolved, hit count = 0 2.2: where = SWTest`SWTest.ViewController.init (SWTest.ViewController.Type)(nibName : Swift.Optional<Swift.String>, bundle : Swift.Optional<__ObjC.NSBundle>) -> SWTest.ViewController + 57 at ViewController.swift, address = 0x00000001070d53f9, resolved, hit count = 0 2.3: where = SWTest`SWTest.ViewController.init (SWTest.ViewController.Type)(coder : __ObjC.NSCoder) -> Swift.Optional<SWTest.ViewController> + 16 at ViewController.swift, address = 0x00000001070d56d0, resolved, hit count = 0 

在加上名字以后,我们就可以通过名字来操作断点了

(lldb) br disable -N leo
1 breakpoints disabled.

在某一个函数上加断点

例如,在准备Person的函数中personLoop添加断点

(lldb) br s -F personLoop
Breakpoint 2: 2 locations.
(lldb) br li
Current breakpoints:
1: file = '/Users/huangwenchen/Desktop/SWTest/SWTest/ViewController.swift', line = 40, locations = 1, resolved = 1, hit count = 11.1: where = SWTest`SWTest.ViewController.viewDidLoad (SWTest.ViewController)() -> () + 75 at ViewController.swift:40, address = 0x000000010f6d51bb, resolved, hit count = 1 2: name = 'personLoop', locations = 2, resolved = 2, hit count = 02.1: where = SWTest`SWTest.Person.personLoop (SWTest.Person)() -> () + 12 at ViewController.swift:25, address = 0x000000010f6d45cc, resolved, hit count = 0 2.2: where = SWTest`@objc SWTest.Person.personLoop (SWTest.Person)() -> () + 4 at ViewController.swift, address = 0x000000010f6d4664, resolved, hit count = 0

条件断点

先在这里加一个断点

当某种条件产生的时候触发的断点,例如停在1000次循环的第800次

然后添加条件,停在i == 80

(lldb) br li
Current breakpoints:
1: file = '/Users/huangwenchen/Desktop/SWTest/SWTest/ViewController.swift', line = 40, locations = 1, resolved = 1, hit count = 11.1: where = SWTest`SWTest.ViewController.viewDidLoad (SWTest.ViewController)() -> () + 75 at ViewController.swift:40, address = 0x00000001094d81bb, resolved, hit count = 1 2: file = '/Users/huangwenchen/Desktop/SWTest/SWTest/ViewController.swift', line = 27, locations = 1, resolved = 1, hit count = 12.1: where = SWTest`SWTest.Person.personLoop (SWTest.Person)() -> () + 111 at ViewController.swift:27, address = 0x00000001094d762f, resolved, hit count = 1 (lldb) br modify -c 'i == 80'
(lldb) po i
80

断点行为

当断点触发的时候,执行的LLDB代码

例如,当i==80的时候,输出sum

(lldb) br li
Current breakpoints:
1: file = '/Users/huangwenchen/Desktop/SWTest/SWTest/ViewController.swift', line = 40, locations = 1, resolved = 1, hit count = 11.1: where = SWTest`SWTest.ViewController.viewDidLoad (SWTest.ViewController)() -> () + 75 at ViewController.swift:40, address = 0x00000001057391bb, resolved, hit count = 1 3: file = '/Users/huangwenchen/Desktop/SWTest/SWTest/ViewController.swift', line = 27, locations = 1, resolved = 1, hit count = 03.1: where = SWTest`SWTest.Person.personLoop (SWTest.Person)() -> () + 111 at ViewController.swift:27, address = 0x000000010573862f, resolved, hit count = 0 (lldb) br modify -c 'i == 80' 3
(lldb) br command add 3
Enter your debugger command(s).  Type 'DONE' to end.
> po sum
> DONEpo sum
3160

其他断点相关

lldb中输入

(lldb) help br set

篇幅限制,不列出help的结果了


类型查找Type

抛出一个异常,不知道是啥的时候怎么办?

(lldb) type lookup CustomError
enum CustomError : ErrorType {case LeoError1case LeoError2var hashValue: Swift.Int {get {}}var _code: Swift.Int {get {}}
}

可以简写

(lldb) ty l CustomError
enum CustomError : ErrorType {case LeoError1case LeoError2var hashValue: Swift.Int {get {}}var _code: Swift.Int {get {}}
}

LLDB中的异常处理

执行一个抛出异常的方法

(lldb) e person.personException()
(SWTest.CustomError) $E0 = LeoError1

流程控制

frame info 查看当前所在的位置

(lldb) frame info
frame #0: 0x000000010573862f SWTest`SWTest.Person.personLoop (self=0x00007fbaf1d054d0)() -> () + 111 at ViewController.swift:27
  • c 继续运行
  • n next 下一行
  • s step in
  • finish step out

函数提前返回

thread return

通过这个命令,可以很好的隔离函数,通常用在函数的最开始位置,避免ARC引用计数问题


最后

欢饮关注我的CSDN博客,很长一段时间内,我会持续的更新iOS/Swift/Objective C相关的文章

LLDB调试的文章应该还有一篇进阶使用的,近期会更新


Swift 代码调试核武-LLDB调试基础相关推荐

  1. Swift 代码调试-善用XCode工具(UI调试,五种断点,预览UIImage...)

    原创Blog,转载请注明出处   http://blog.csdn.net/hello_hwc?viewmode=list  我的stackoverflow 工欲善其事,必先利其器,强烈建议新手同学好 ...

  2. mysql length函数_初识LLDB 调试 MySQL-爱可生

    作者:洪斌 MySQL数据库最大的优势,想必就是可以直接通过代码调试来学习数据库内部逻辑.任何问题.任何疑惑在debug源码面前都无法掩盖,还可以提升对数据库内核的理解能力,是不是有一种可以掌控一切的 ...

  3. Bug调试(lldb)

    原文网址:http://www.cnblogs.com/Twisted-Fate/p/4760156.html 今天博主有一些Bug调试的需求,遇到了一些困难点,在此和大家分享,希望能够共同进步. X ...

  4. pycharm连接远程服务器并进行代码上传+远程调试

    Pycharm连接远程服务器并进行代码上传+远程调试 </h1><div class="clear"></div><div class=& ...

  5. lldb调试使用python脚本问题总结

    lldb调试器可以使用python脚本实现功能增强,但也不是可以随心所欲的,在实际中有很多地方需要注意. 首先是对多线程环境调试使用python脚本,也要考虑python脚本有多线程安全,尤其是有许多 ...

  6. centos7 lldb 调试netcore应用的内存泄漏和死循环示例(dump文件调试)

    写个demo来玩一玩linux平台下使用lldb加载sos来调试netcore应用. 当然,在真实的产线环境中需要分析的数据和难度远远高于demo所示,所以demo的作用也仅仅只能起到介绍工具的作用. ...

  7. Android Studio新手–下载安装配置–零基础入门–基本使用–调试技能–构建项目基础–使用AS应对常规应用开发

    转自:http://blog.csdn.net/yanbober/article/details/45306483 目标:Android Studio新手–>下载安装配置–>零基础入门–& ...

  8. LLDB调试基本使用

    在平时开发中,我们可能需要调试某些东西,比如查看给服务器发请求时传过去的参数,如果不适用LLDB的话我们用的最多的就是通过NSLog方式去打印,但现在我们可以精简这个步骤,那就是使用LLDB调试命令. ...

  9. 使用Python脚本强化LLDB调试器

    https://www.cnblogs.com/yuanxiaoping_21cn_com/p/5433286.html LLDB是Xcode自带的调试器,作为一个iOS应用开发程序员,平时我在开发应 ...

最新文章

  1. CV算法复现(分类算法2/6):AlexNet(2012年 Hinton组)
  2. unitoy机器人怎么联网_机器人操作说明
  3. plsql连接不上64位oracle,plsql develope连接64位Oracle 11g出错解决方案(图)
  4. 沙溪理工学校计算机,学雷锋树新风——沙溪理工学校计算机部开展学雷锋活动...
  5. 人脸识别大规模爆发!
  6. 《大数据分析原理与实践》——习题
  7. bash-shell高级编程--操作符与相关主题
  8. aop执行跳过某个方法_简谈前端开发中的AOP(一) -- 前端AOP的实现思路
  9. Swift - 重写导航栏返回按钮
  10. LeetCode 动态规划《简单》部分 Python实现
  11. 我的docker随笔36:定制jenkins镜像
  12. 通过分区(Partition)提升MySQL性能
  13. idea代码补全_IDEA中有哪些让你相见恨晚的技巧?
  14. 彻底清除计算机磁盘上的病毒,电脑硬盘病毒无法彻底删除怎么办
  15. python爬虫能当副业吗?有哪些平台能接单?
  16. [1.2.0新功能系列:二] Apache Doris 1.2.0 JDBC外表 及 Mutil Catalog
  17. kaggle泰坦尼克号_Kaggle基础知识:泰坦尼克号比赛
  18. Ceres Solver 官方教程学习笔记(十二)——非线性最小二乘法建模Modeling Non-linear Least Squares (下)
  19. Advanced Computer Network Review(5)——COPE
  20. Matlab图像数据类型unit8,double关系

热门文章

  1. Iterator<E>
  2. Web安全工具—nc(瑞士军刀)持续更新
  3. 最全的androidStudio插件
  4. 汇编中的lea指令的作用,简单清晰明了不废话!
  5. 各大互联网公司PUA套路,同行必须懂!!!
  6. 100个python算法超详细讲解:牛顿迭代法求方程根
  7. Xposed模块开发教程,该篇讲解通俗易懂,所以转发
  8. 2023年留学生入户广州户口条件会有哪些
  9. 个人中心修改用户头像
  10. 我们的UED设计流程及方法