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. 通向从容之道——Getting things done读书笔记

    一.主要的两个目的:         1. 抓住所有一切需要处理的事情:         2. 训练自己在接受一切"输入信息"的前期作出决定.   二.目前的问题:         ...

  2. ubuntu 13.10 install wireshark

    ubuntu 13.10 install wireshark 今天在使用java jsoup操作remote server的是否,在本地执行可以成功返回内容,然后打成jar包,使用shell在 ser ...

  3. Android Studio 插件开发详解二:工具类

    转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/78112856 本文出自[赵彦军的博客] 在插件开发过程中,我们按照开发一个正式的项 ...

  4. linux下安装apc

    wget htdtp://pecl.php.net/get/APC tar zxvf APC-3.1.3p.tgz cd APC-3.1.3p /usr/local/php/bin/phpize ./ ...

  5. 使用ASP.NET SignalR实现一个简单的聊天室

    前言 距离我写上一篇博客已经又过了一年半载了,时间过得很快,一眨眼,就把人变得沧桑了许多.青春是短暂的,知识是无限的.要用短暂的青春,去学无穷无尽的知识,及时当勉励,岁月不待人.今天写个随笔小结记录一 ...

  6. birt4.6部署到tomcat及启动服务报错解决方法

    一.下载birt-runtime-4.6.0-20160607.zip包 解压后birt-runtime-4.6.0-20160607\WebViewerExample将WebViewerExampl ...

  7. 解决0% [Waiting for headers] 导致的unable to lock the administration directory (/var/lib/dpkg/) is another process using it

    这是我在配置vim的YouCompleteMe时遇到的问题,我需要使用CMake来编译YCM. 在我输入 $ sudo apt install cmake 由于网络原因导致安装一直卡在0% [Wait ...

  8. 分析DuxCms之AdminController

    /** * 后台模板显示 调用内置的模板引擎显示方法, * @access protected * @param string $templateFile 指定要调用的模板文件 * @return v ...

  9. python_汉塔诺

    '''据说古代有一个梵塔,塔内有三个底座A.B.C,A座上有64个盘子,盘子大小不等,大的在下,小的在上.有一个和尚想把这64个盘子从A座移到C座,但每次只能允许移动一个盘子,在移动盘子的过程中可以利 ...

  10. C++相关:C++的IO库

    前言 基本的IO库设施 istream(输入流类型),提供输入操作. ostream(输出流类型),提供输出操作. cin,一个istream对象,从标准输入读取数据. cout,一个ostream对 ...