LLDB 调试命令、插件和技巧(上)

简介: LLDB 调试命令、插件和技巧(上)

原生


p/po 命令

  • p 打印基本数据类型的值,查看对象返回对象的指针地址(不可以用宏)。
  • po 打印对象的描述,常量、变量、表达式返回的对象等。
(lldb) p p1
(Person *) $0 = 0x000061200023130
(lldb) po p1
<Person *): 0x000061200023130>


e 命令

给具体变量赋值。

if dataArray.count == 0 {
   print("dataArray is empty")
}

if 处断点,控制台输入 e dataArray.count = 0 回车,继续运行即可。


call 命令

动态调用函数。

(lldb) po cell.contentView.subviews
<__NSArrayM 0x60800005f5f0>(
<UILabel: 0x7f91f4f18c90; frame = (5 5; 300 25); text = '2 - Drawing index is top ...'; userInteractionEnabled = NO; tag = 1; layer = <_UILabelLayer: 0x60800009ff40>>,
<UIImageView: 0x7f91f4d20050; frame = (105 20; 85 85); opaque = NO; userInteractionEnabled = NO; tag = 2; layer = <CALayer: 0x60000003ff60>>,
<UIImageView: 0x7f91f4f18f10; frame = (200 20; 85 85); opaque = NO; userInteractionEnabled = NO; tag = 3; layer = <CALayer: 0x608000039860>>
)
(lldb) call [label removeFromSuperview]
(lldb) po cell.contentView.subviews
<__NSArrayM 0x600000246de0>(
<UIImageView: 0x7f91f4d20050; frame = (105 20; 85 85); opaque = NO; userInteractionEnabled = NO; tag = 2; layer = <CALayer: 0x60000003ff60>>,
<UIImageView: 0x7f91f4f18f10; frame = (200 20; 85 85); opaque = NO; userInteractionEnabled = NO; tag = 3; layer = <CALayer: 0x608000039860>>
)

动态将 cell 的某个子视图移除。


bt 命令

打印线程的堆栈信息(bt all 打印全部线程堆栈信息)。

(lldb) bt 
* thread #1: tid = 0x27363, 0x000000010d204125 TestDemo`-[FifthViewController tableView:cellForRowAtIndexPath:](self=0x00007f91f4e153c0, _cmd="tableView:cellForRowAtIndexPath:", tableView=0x00007f91f5889600, indexPath=0xc000000000400016) + 2757 at FifthViewController.m:91, queue = 'com.apple.main-thread', stop reason = breakpoint 6.1
* frame #0: 0x000000010d204125 TestDemo`-[FifthViewController tableView:cellForRowAtIndexPath:](self=0x00007f91f4e153c0, _cmd="tableView:cellForRowAtIndexPath:", tableView=0x00007f91f5889600, indexPath=0xc000000000400016) + 2757 at FifthViewController.m:91
frame #1: 0x0000000111d0a7b5 UIKit`-[UITableView _createPreparedCellForGlobalRow:withIndexPath:willDisplay:] + 757
frame #2: 0x0000000111d0aa13 UIKit`-[UITableView _createPreparedCellForGlobalRow:willDisplay:] + 74
frame #3: 0x0000000111cde47d UIKit`-[UITableView _updateVisibleCellsNow:isRecursive:] + 3295
frame #4: 0x0000000111d13d95 UIKit`-[UITableView _performWithCachedTraitCollection:] + 110
frame #5: 0x0000000111cfa5ef UIKit`-[UITableView layoutSubviews] + 222
frame #6: 0x0000000111c61f50 UIKit`-[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 1237
frame #7: 0x00000001117a5cc4 QuartzCore`-[CALayer layoutSublayers] + 146
(lldb)


image 命令

列出当前 App 中的所有 module,可以查看某一个地址对应的代码位置。


image lookup -address

查找崩溃位置

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

当遇到 crash 时,查看线程栈,只能看到栈帧的地址,使用 image lookup –address 地址 可以方便的定位到这个地址对应的代码行。


image lookup -name

查找方法来源。

(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


image lookup –type

查看成员

(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"


breakpoint

breakpoint set -f xxx -l xxx

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


breakpoint set -n func name

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

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


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


breakpoint set -c "xxxx"

条件断点操作。

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


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


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


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


command alias

自定义别名。

(lldb) command alias see thread backtrace
(lldb) see 5
  thread #5
    frame #0: 0x000000010bd3544e libsystem_kernel.dylib`__workq_kernreturn + 10
    frame #1: 0x000000010bd69621 libsystem_pthread.dylib`_pthread_wqthread + 1426
    frame #2: 0x000000010bd6907d libsystem_pthread.dylib`start_wqthread + 13


command alias %1 %2

自定义别名带参数。

(lldb) command alias dlt breakpoint delete %1
(lldb) breakpoint list
Current breakpoints:
3: file = 'JSONKit.m', line = 725, exact_match = 0, locations = 1, resolved = 1, hit count = 0
  3.1: where = TEST`-[JKArray dealloc] + 20 at JSONKit.m:727, address = 0x00000001073360c4, resolved, hit count = 0
(lldb) dlt 3
1 breakpoints deleted; 0 breakpoint locations disabled.

lldb 初始化时会读取 ~/.lldbinit 文件,可以把简写命令写进此文件中。


  1. 打开终端,输入 vi ~/.lldbinit 进入文件编辑。
  2. 写入自定义内容,如:command alias 堆栈 thread backtrace
  3. 然后 ESC 键,出现冒号后输入 wqenter 键保存并退出编辑。


menthods

打印当前对象的属性和方法。

(lldb) methods p1
<Person: 0x60000003eac0> : 
in Person:
    Properties:
        @property (copy, nonatomic) NSString* name; (@synthesize name = _name;) 
        @property (nonatomic) long age; (@synthesize age = _age; )
    Instance Methods:
        - (void) eat; (0x1098bf3e0)
        - (void) .cxx_destruct; (0x1098bf4fo)
        - (id) description; (0x1098bf410)
        - (id) name; (0x1098bf430)
(NSObject . . )


pachtion

打印对象调用者及方法。

(lldb) pactions 0x7fcdhsja212728
<ViewController: 0x7fcdhsja212728>: login:


pclass

打印对象继承关系。

pcalss s
Student
    | Preson
    |   | NSObject


presponder

打印响应者链。

(lldb) presponder 0x7ff1ab5a6770
<UIView: 0x7ff1ab5a6770; frame = (75 362; 123 96); autoresize = RM+BM; layer = <CALayer: 0x7ff1ab5a10a0>>
   | <UIView: 0x7ff1ab5a6660; frame = (0 0; 320 568); autoresize = W+H; layer = <CALayer: 0x7ff1ab5a23c0>>
   |    | <test.ViewController: 0x7ff1ab6380a0>
   |    |    | <UIWindow: 0x7ff1ab411de0; frame = (0 0; 320 568); gestureRecognizers = <NSArray: 0x7ff1ab409a20>; layer = <UIWindowLayer: 0x7ff1ab417a90>>
   |    |    |    | <UIApplication: 0x7ff1ab528330>
   |    |    |    |    | <test.AppDelegate: 0x7ff1ab40f050>


search

搜索栈内控件及其子控件。

search UIButton
<UIButton: 0x7fc373828111; frame = (0 0; 100 90);
opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x608000221060>>

lookup 搜索,可执行正则表达式。


目录
相关文章
VSCode调试 添加命令行参数
VSCode调试 添加命令行参数
470 0
|
监控 NoSQL
JLink + GDB 调试方法
本节主要介绍嵌入式开发中常用的JLink+GDB调试方法。 调试所需软件 J-link,可以从https://www.segger.com下载对应操作系统的软件包,然后安装(注意:segger是仿真器的名字,相当常用的一款,仿真器的接口也是固定的,一般开发版上都会带有这个调试接口,如图) 运行JLinkGDBServer 按照上图中的配置,配置GDBServer,然后点击OK,进入下一个界面 注意,如果硬件连接没有问题,那么上图中的J-Link和 Device栏中显示绿色,GDB显示为红色,因为我们还没有运行GDB软件。
7351 46
|
5月前
|
Linux Swift iOS开发
LLDB:强大的源代码级调试工具
LLDB:强大的源代码级调试工具
308 0
|
6月前
|
JSON NoSQL C++
VScode调试C/C++项目调试多个C++程序makefile
VScode调试C/C++项目调试多个C++程序makefile
191 0
|
6月前
|
NoSQL Linux Android开发
OPENJTAG调试学习(三):使用 gdb 命令行进行调试
OPENJTAG调试学习(三):使用 gdb 命令行进行调试
112 0
|
NoSQL Linux 网络安全
【Linux C】GCC编译 && GDB调试 从入门到放弃 (gcc调试选项详解、gdb调试、条件断点、远程调试、脚本化调试)(二)
阅读本文可能需要一些基础,比如:C语言基础、Linux基础操作、vim、防火墙等。篇幅有限,本文讲的“比较浅显”。 通过本文你将学会: gcc编译 gdb调试
|
NoSQL IDE Linux
【Linux C】GCC编译 && GDB调试 从入门到放弃 (gcc调试选项详解、gdb调试、条件断点、远程调试、脚本化调试)(一)
阅读本文可能需要一些基础,比如:C语言基础、Linux基础操作、vim、防火墙等。篇幅有限,本文讲的“比较浅显”。 通过本文你将学会: gcc编译 gdb调试
3.4bochs的调试方法
3.4bochs的调试方法
268 0
|
算法 关系型数据库 芯片
MDK 用Jlink调试无法使用断点
MDK 用Jlink调试无法使用断点
754 0
MDK 用Jlink调试无法使用断点
|
缓存 JavaScript 前端开发