LLDB是个开源的内置于XCode的调试工具,这里来理一理常用用法。
lldb对于命令的简称,是头部匹配方式,只要不混淆,你可以随意简称某个命令。结果为在xcode下验证所得,可能与其它平台有所误差。

1 打印值、修改值、调用方法

1.1 p、po 打印值

打印相关的命令有:p、po。
p 和 po 的区别在于使用 po 只会输出对应的值,而 p 则会返回值的类型以及命令结果的引用名。

(lldb) p width
(CGFloat) $10 = 70
(lldb) po width
70
(lldb) p endTime
(__NSCFString *) $14 = 0x0000608000437660 @"08-11 11:43"
(lldb) po endTime
08-11 11:43

对比结果:

po:输出值
p:输出值+值类型+引用名+内存地址(xcode中有内存地址,其它平台不确定)
除此之外,p还隐藏了一个有意思的功能,常量的进制转换:

//默认打印为10进制
(lldb) p 100
(int) $8 = 100
//转16进制
(lldb) p/x 100
(int) $9 = 0x00000064
//转8进制
(lldb) p/o 100
(int) $10 = 0144
//转二进制
(lldb) p/t 100
(int) $2 = 0b00000000000000000000000001100100
//字符转10进制数字
(lldb) p/d 'A'
(char) $7 = 65
//10进制数字转字符
(lldb) p/c 66
(int) $10 = B\0\0\0

1.2 expression 修改参数值

感觉exp命令是调试过程中最有价值有命令了,它可以打印值、修改值。

//expression打印值
(lldb) expression width
(CGFloat) $5 = 67
//expression修改值
(lldb) expression width = 80
(CGFloat) $6 = 80
//打印修改后结果
(lldb) p width
(CGFloat) $7 = 80
(lldb)

expression:同样可以输出值+值类型+引用名,但其一般用于修改。

1.3 call 方法调用

在断点调用某个方法,并输出此方法的返回值。

(lldb) call width
(CGFloat) $12 = 70
(lldb) call endTime
(__NSCFString *) $16 = 0x0000608000437660 @"08-11 11:43"

call:同样为输出值+值类型+引用名

2 Thread

2.1 堆栈打印 thread backtrace

如果嫌堆栈打印太长,可以加一个值限制,如bt 10,只打印

(lldb) bt 10
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
 * frame #0: 0x00000001005e4906 DiDi`-[FW_HomeCell_HotBill setDataSource:](self=0x00007fd3938a7800, _cmd="setDataSource:", dataSource=0x00006080001c8bb0) at FW_HomeCell.m:357
   frame #1: 0x00000001009a9fd7 DiDi`-[FW_MyHomeTableView tableView:cellForRowAtIndexPath:](self=0x00007fd3921fec00, _cmd="tableView:cellForRowAtIndexPath:", tableView=0x00007fd3921fec00, indexPath=0xc000000000000316) at FW_MyHomeTableView.m:247
   frame #2: 0x00000001055a2ab2 UIKit`-[UITableView _createPreparedCellForGlobalRow:withIndexPath:willDisplay:] + 750
   frame #3: 0x00000001055a2cf8 UIKit`-[UITableView _createPreparedCellForGlobalRow:willDisplay:] + 74
   frame #4: 0x0000000105577639 UIKit`-[UITableView _updateVisibleCellsNow:isRecursive:] + 2845
   frame #5: 0x00000001055abccc UIKit`-[UITableView _performWithCachedTraitCollection:] + 111
   frame #6: 0x0000000105592e7a UIKit`-[UITableView layoutSubviews] + 233
   frame #7: 0x00000001054f955b UIKit`-[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 1268
   frame #8: 0x0000000105114904 QuartzCore`-[CALayer layoutSublayers] + 146
   frame #9: 0x0000000105108526 QuartzCore`CA::Layer::layout_if_needed(CA::Transaction*) + 370

2.2 thread return 跳出当前方法的执行

Debug的时候,也许会因为各种原因,我们不想让代码执行某个方法,或者要直接返回一个想要的值。这时候就该thread return上场了。
有返回值的方法里,如:numberOfSectionsInTableView:,直接thread return 10,就可以直接跳过方法执行,返回10.

//跳出方法
(lldb) thread return
//让带有返回int值的方法直接跳出,并返回值10
(lldb) thread return 10

2.3 流程控制

实际上使用xcode自带的可视化工具来控制“继续”“暂停”“下一步”“进入”“跳出”更简单

继续:continue, c
下一步:next, n
进入:step, s
跳出:finish, f

2.4 跳帧 frame select N

2.1中打印有10帧,如果我想跳转到第1帧:frame select 1

(lldb) frame select 1
frame #1: 0x0000000105e91c3c DiDi`-[FW_HomeViewController tableView:cellForRowAtIndexPath:](self=0x00007fbf9f73b410, _cmd="tableView:cellForRowAtIndexPath:", tableView=0x00007fbfa11dc400, indexPath=0xc000000000a00316) at FW_HomeViewController.m:597
  594                  break;
  595                  
  596                  case 3: {
-> 597                      cell.[4md[0mataSource = _hotBills[indexPath.row];
  598                      cell.textSelect = ^(UITextField *text) {
  599                          weakSelf.curruntText = text;
  600                      };

2.5 查看帧变量 frame variable

(lldb) frame variable
(FW_HomeViewController *) self = 0x00007faccbf587d0
(SEL) _cmd = "tableView:cellForRowAtIndexPath:"
(UITableView *) tableView = 0x00007faccd09b400
(NSIndexPath *) indexPath = 0xc000000000000316
(FW_HomeViewController *) weakSelf = 0x00007faccbf587d0
(FW_HomeCell_HotBill *) cell = 0x00007faccc101a00
(UIView *) model = 0x00007fff52c13d90
(FW_HomeCell_HotBill *) billCell = 0x00000001124e99f6

3 Image

3.1 image lookup -address 查找崩溃位置

当你遇见数组崩溃,你又没有找到崩溃的位置,只扔给你一堆报错信息,这时候image lookup来帮助你。如下

0   CoreFoundation                      0x0000000103209b0b __exceptionPreprocess + 171
   1   libobjc.A.dylib                     0x00000001079db141 objc_exception_throw + 48
   2   CoreFoundation                      0x000000010313effb -[__NSArrayM objectAtIndex:] + 203
   3   DiDi                                0x00000001009a9f3a -[FW_MyHomeTableView tableView:cellForRowAtIndexPath:] + 1322
   4   UIKit                               0x00000001055a2ab2 -[UITableView _createPreparedCellForGlobalRow:withIndexPath:willDisplay:] + 750
   5   UIKit                               0x00000001055a2cf8 -[UITableView _createPreparedCellForGlobalRow:willDisplay:] + 74
   6   UIKit                               0x0000000105577639 -[UITableView _updateVisibleCellsNow:isRecursive:] + 2845
   7   UIKit                               0x00000001055abccc -[UITableView _performWithCachedTraitCollection:] + 111
   8   UIKit                               0x0000000105592e7a -[UITableView layoutSubviews] + 233
   9   UIKit                               0x00000001054f955b -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 1268
   10  QuartzCore                          0x0000000105114904 -[CALayer layoutSublayers] + 146

寻找自己项目的标识,看到frame3位置,你只需这样查找位置:

image lookup -a 0x00000001009a9f3a
     Address: DiDi[0x0000000100609f3a] (DiDi.__TEXT.__text + 6323194)
     Summary: DiDi`-[FW_MyHomeTableView tableView:cellForRowAtIndexPath:] + 1322 at FW_MyHomeTableView.m:243

项目中FW_MyHomeTableView.m:243,perfect!

3.2 image lookup -name 查找方法来源

此命令可以用来查找方法的来源。包括在第三方SDK中的方法,也能被查到。
例:查找transformOtherModelToSuit:

(lldb) image lookup -n transformOtherModelToSuit:
1 match found in /Users/xxx/Library/Developer/Xcode/DerivedData/DiDi-cwpbvvyvqmeijmcjnneothzuthsy/Build/Products/Debug-iphonesimulator/DiDi.app/DiDi:
       Address: DiDi[0x0000000100293d60] (DiDi.__TEXT.__text + 2693664)
       Summary: DiDi`+[FW_BetFunction transformOtherModelToSuit:] at FW_BetFunction.m:107

3.3 image lookup –type 查看成员

查看某个class的所有属性和成员变量。不过貌似frameWork库中文件不能查看。

(lldb) image lookup -t MatchEvent
1 match found in /Users/xxxx/Library/Developer/Xcode/DerivedData/DiDi-cwpbvvyvqmeijmcjnneothzuthsy/Build/Products/Debug-iphonesimulator/DiDi.app/DiDi:
id = {0x00433d32}, name = "MatchEvent", byte-size = 48, decl = MatchEvent.h:11, compiler_type = "@interface MatchEvent : NSObject{
   BOOL _isHome;
   NSString * _playerName;
   NSString * _timePoint;
   NSString * _eventType;
   NSString * _eventDesc;
}
@property ( getter = isHome,setter = setIsHome:,assign,readwrite,nonatomic ) BOOL isHome;
@property ( getter = playerName,setter = setPlayerName:,readwrite,copy,nonatomic ) NSString * playerName;
@property ( getter = timePoint,setter = setTimePoint:,readwrite,copy,nonatomic ) NSString * timePoint;
@property ( getter = eventType,setter = setEventType:,readwrite,copy,nonatomic ) NSString * eventType;
@property ( getter = eventDesc,setter = setEventDesc:,readwrite,copy,nonatomic ) NSString * eventDesc;
@end"

4 breakpoint

4.1 文件名+行号 breakpoint set -f xxx -l xxx

我们平时操作xcode,在某一行点下断点,其实操作的就是这个命令。

(lldb) breakpoint set -f FW_ProfilesDetailModel.m -l 95
Breakpoint 3: where = DiDi`-[FW_ProfilesDetailModel incomeRate] + 27 at FW_ProfilesDetailModel.m:96, address = 0x0000000105b404bb

4.2 函数名断点

4.2.1 方法名断点 breakpoint set -n 方法名

(lldb) breakpoint set -n viewDidLoad
Breakpoint 4: 414 locations.

Tips:这里要说一下,xcode其实也有函数名断点,不过用breakpoint set -n实现,比xcode下断点快N倍,不过xcode下的断点还给提示所有断到的位置。

4.2.2 类中方法断点 breakpoint set -n “-[类名 方法名]”

(lldb) breakpoint set -n "-[FW_MyHomeViewController viewDidLoad]"
Breakpoint 8: where = DiDi`-[FW_MyHomeViewController viewDidLoad] + 20 at FW_MyHomeViewController.m:58, address = 0x0000000105aec944

注意:-[FW_MyHomeViewController viewDidLoad],外面一定要加双引

号,不然会误识别为-[FW_MyHomeViewController`

4.3 条件断点 breakpoint set -c “xxxx”

和xcode中symbolic Breakpoint功能相同,我在FW_HomeCell.m 362行下断点,但又想过滤仅width>68的状态,操作如下:

breakpoint set -f FW_HomeCell.m -l 362 -c "width > 68"
Breakpoint 5: where = DiDi`-[FW_HomeCell_HotBill setDataSource:] + 2006 at FW_HomeCell.m:363, address = 0x000000010d22e0a6

4.4 查看断点列表 breakpoint list

(lldb) breakpoint list
Current breakpoints:
8: name = '-[FW_MyHomeViewController viewDidLoad]', locations = 1, resolved = 1, hit count = 2
8.1: where = DiDi`-[FW_MyHomeViewController viewDidLoad] + 20 at FW_MyHomeViewController.m:58, address = 0x0000000105aec944, resolved, hit count = 2
9: file = '/Users/xxxx/didi-ios/DiDi/FollowWinner/Model/FW_HomeModel.m', line = 24, exact_match = 0, locations = 1, resolved = 1, hit count = 0
9.1: where = DiDi`+[FW_HomeModel_Rank parasWithDict:limitNickLength:] + 89 at FW_HomeModel.m:24, address = 0x00000001061bc169, resolved, hit count = 0

4.5 禁用/启用断点 breakpoint disable/enable

//禁用断点
(lldb) breakpoint disable 9
1 breakpoints disabled.
(lldb) breakpoint list
Current breakpoints:
9: file = '/Users/zmz/didi-ios/DiDi/FollowWinner/Model/FW_HomeModel.m', line = 24, exact_match = 0, locations = 1 Options: disabled
9.1: where = DiDi`+[FW_HomeModel_Rank parasWithDict:limitNickLength:] + 89 at FW_HomeModel.m:24, address = 0x00000001061bc169, unresolved, hit count = 0
//启用断点
(lldb) breakpoint enable 9
1 breakpoints enabled.
(lldb) breakpoint list
Current breakpoints:
9: file = '/Users/zmz/didi-ios/DiDi/FollowWinner/Model/FW_HomeModel.m', line = 24, exact_match = 0, locations = 1, resolved = 1, hit count = 0
9.1: where = DiDi`+[FW_HomeModel_Rank parasWithDict:limitNickLength:] + 89 at FW_HomeModel.m:24, address = 0x00000001061bc169, resolved, hit count = 0

4.6 移除断点 breakpoint delete

(lldb) breakpoint delete 8
1 breakpoints deleted; 0 breakpoint locations disabled.
(lldb) breakpoint list
Current breakpoints:
9: file = '/Users/xxxx/didi-ios/DiDi/FollowWinner/Model/FW_HomeModel.m', line = 24, exact_match = 0, locations = 1, resolved = 1, hit count = 0
9.1: where = DiDi`+[FW_HomeModel_Rank parasWithDict:limitNickLength:] + 89 at FW_HomeModel.m:24, address = 0x00000001061bc169, resolved, hit count = 0

结语:

有了这些命令,调试起来肯定就得心应手了。总结下常用的,供多看几遍加深回忆:

堆栈相关:bt查看堆栈、frame select跳帧、frame variable查看帧参数、thread return跳出当前执行、【step/finish/next/continue】进入/跳出/下一步/跳出本断点

断点相关:breakpoint set -f -l -c条件断点、breakpoint set -n方法断点、breakpoint delete断点移除、breakpoint list断点列表

image命令:image lookup -address崩溃定位、image lookup -name方法来源、 image lookup –type 查看成员

LLDB支持简写

iOS之LLDB常用调试命令的更多相关文章

  1. gdb常用调试命令

    一般来说,GDB主要帮忙你完成下面四个方面的功能: 1.启动你的程序,可以按照你的自定义的要求随心所欲的运行程序.    2.可让被调试的程序在你所指定的调置的断点处停住.(断点可以是条件表达式)   ...

  2. GDB常用调试命令以及多进程多线程调试

    http://blog.csdn.net/freeelinux/article/details/53700266 一:普通命令   1.list命令 list  linenum      显示程序第l ...

  3. GDB常用调试命令(一)

    GDB是UNIX及UNIX-like下的调试工具,通常gdb使用前置条件:编译时加入debug信息,这里指的是C++. gcc/g++调试选项   gcc/g++是在编译时加入-g,-g分4个等级: ...

  4. gdb常用调试命令以及多线程堆栈的查看

    GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具.或许,各位比较喜欢那种图形界面方式的,像VC.BCB等IDE的调试,但如果你是在UNIX平台下做软件,你会发现GDB这个调试工具有比VC ...

  5. GDB常用调试命令(二)

    GDB信号处理 在GDB中使用handle命令定义一个信号处理.信号可以以SIG开头或不以 SIG开头,可以用定义一个要处理信号的范围(如:SIGIO-SIGKILL,表示处理从SIGIO信号到SIG ...

  6. puppet常用调试命令

    yum快速部署puppet测试环境(C/S端) rpm -ivh  http://yum.puppetlabs.com/puppetlabs-release-el-7.noarch.rpm yum r ...

  7. gdb 常用调试命令

    1.   file    quit 2.   frame bt 3.   finish 运行程序,直到当前函数完成返回,并打印函数返回时的堆栈地址和返回值及参数信息. until 当要退出在一个循环体 ...

  8. squid常用调试命令

    解压,编译,make ,make install 就不说了.从 make install 后开始.当你的 squid.conf 配置文档按照你的想法修改完以后,启动 squid 之旅就开始了.1,初始 ...

  9. npm和yarn常用调试命令

    yarn查看全局安装路径 yarn global dir npm查看所有全局安装的包<全局路径也会显示> npm list --depth=0 -global

随机推荐

  1. webpack 4.x 遇到的错误

    由于之前重装电脑,很多之前的小Demo 现在都跑不起来.特别是webpack一直在报错. webpack 安装node 全局安装webpack,webpack-cli(一定要全局安装) 项目初始化 w ...

  2. Binary Tree Zigzag Level Order Traversal(z字形打印二叉树)

    Given a binary tree, return the zigzag level order traversal of its nodes' values. (ie, from left to ...

  3. RocketMQ源码 — 七、 RocketMQ高可用(2)

    上一篇说明了RocketMQ怎么支持broker集群的,这里接着说RocketMQ实现高可用的手段之一--冗余. RocketMQ部署的时候一个broker set会有一个mater和一个或者多个sl ...

  4. zinnia项目功能分析

    Zinnia是基于Django开发的一个开源博客系统,近期为了写一个类博客系统特对它做功能分析,+号的多少表明这个功能对于博客的重要性: ++评论:Comments 站点图:Sitemaps ]压缩视 ...

  5. 理解Python中的类对象、实例对象、属性、方法

    class Animal(object): # 类对象 age = 0 # 公有类属性 __like = None # 私有类属性 def __init__(self): # 魔法方法 self.na ...

  6. Apache 、Tomcat、Nginx的区别

    一. 定义: 1. Apache Apache HTTP服务器是一个模块化的服务器,可以运行在几乎所有广泛使用的计算机平台上.其属于应用服务器.Apache支持支持模块多,性能稳定,Apache本身是 ...

  7. 报错:严重: Servlet.service() for servlet [springmvc] in context with path [ ] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause

    解决:service类或dao类需要@Autowired

  8. NIO之FileChannel类的理解和使用

    文章链接:http://blog.csdn.net/qq_16628781/article/details/70532307 知识点: FileChannel类及方法理解: 普通输入输出流复制文件: ...

  9. mybatis设置callSettersOnNulls解决返回字段不全的问题

    Spring+MyBatis开发过程中,在xxMapper.xml配置文件进行select查询时resultType="map",如果要查询的字段是空值,在返回的map中会出现找不 ...

  10. Java 精简Jre jar打包成exe

    #开始 最近几天都在忙一个事情,那就是尝试精简jre,我想不明白为什么甲骨文官方不出exe打包工具... 网络上精简jre的文章很多,但是原创的似乎没几个,绝大多数都是转发同一个博客, 这里借鉴了不少 ...