iOS 开发之 LLDB 常用调试技巧

·  阅读 1259
原文链接: devthinking.com

iOS开发之LLDB常用调试技巧
用好了LLDB,让调试变得轻松愉快,本文会写出并示例讲解一些常用的指令,以让你爱上它~~
Debug的技巧有NSLog, LLDB, 但是NSLog效率低下,尽量少用NSLog。LLDB中强大的功能,完全能取代NSLog。

调试技巧:NSLog

NSLog比printf的效率要低几十倍,因为NSLog会向ASL写log,同时向Terminal写log,而且同时会出现在Console.app中。NSLog尽量不要在release中打开,在Debug中可以写一个宏:

#ifdef DEBUG
#define NSLog(FORMAT, ...) do {fprintf(stderr,"%s:%d\t%s\n",[[[NSString stringWithUTF8String:__FILE__] lastPathComponent] UTF8String], __LINE__, [[NSString stringWithFormat:FORMAT, ##__VA_ARGS__] UTF8String]);} while(0)
#else
#define NSSLog(...)
#endif
复制代码

调试技巧:LLDB

设置断点

  • 在LLDB中设置断点,可以用breakpoint set命令(简写br set):
(lldb) br set -f WebpImageViewController.m -l 104
Breakpoint 10: where = DemoCollectOC`-[WebpImageViewController addTestButton] + 26 at WebpImageViewController.m:104, address = 0x000000010f8a859a
复制代码
  • 用b也可以创建断点,不过格式不同:
(lldb) b WebpImageViewController.m:97
Breakpoint 12: where = DemoCollectOC`-[WebpImageViewController testDict] + 588 at WebpImageViewController.m:97, address = 0x000000010f8a84ac
复制代码
  • b也可以在C语言函数上直接创建,断点停在函数的开始:
(lldb) b DecodeInto
Breakpoint 13: where = DemoCollectOC`DecodeInto + 30 at webp.c:453, address = 0x000000010f95977e
复制代码
  • 也可以在自定义函数、OC函数上设置断点:
(lldb) br set -F "-[UIView setBackgroundColor:]"
Breakpoint 14: where = UIKit`-[UIView(Rendering) setBackgroundColor:], address = 0x0000000112acae65
复制代码
  • Condition & Action断点
    在断点处右键编辑断点,Log Message可以在符合条件时断住并打印出自定义信息:Condition断点图, 还有全局断点,符号断点。

  • 断点继续运行

thread return
复制代码

打印当前线程堆栈:bt

打印所有线程中堆栈bt all

寻找栈地址对应代码位置: image

image lookup --address 0x000000000000
复制代码

常用的po

po可以打印一个对象,p可以打印基本数据类型,po也可以打印出视图的层级关系:[self.view recursiveDescription],但打印不出frame,打印frame可以使用call来调用一句代码:call self.view.frame

LLDB更新UI

查看App整个层次:

(lldb) po [[[UIApplication sharedApplication] keyWindow] recursiveDescription]
; layer = >
   | ; layer = >
   |    | >
   |    |    | >
   |    |    |    | >
   |    |    |    |    | <_UILayoutGuide: 0x7f96c7f11040; frame = (0 0; 0 64); hidden = YES; layer = >
   |    |    |    |    | <_UILayoutGuide: 0x7f96c7c01550; frame = (0 667; 0 0); hidden = YES; layer = >
   |    |    |    |    | 复制代码

在当前断点下,展示的为UITableView: 0x7f96c801a000,取到这个view:

(lldb) e id $myview = (id)0x7f96c801a000
复制代码

改变颜色:

(lldb) e (void)[$myview setBackgroundColor:[UIColor redColor]]
复制代码

我不想继续运行程序,还能看到颜色变化,也可以做到。渲染服务是一个另外的进程(backboardd),调试内容所在的进程被打断了,backdboardd也在运行着,可以用下面的命令也即时展示颜色改变:

(lldb) e (void)[CATransaction flush]
复制代码

查找UIButton的target

如果你在LLDB中有一个button变量,可以新创建的,也可以是在UI中找到的,或者是断点处正在这个变量上,假设是断点在这个testButton变量上:

(lldb) po [testButton allTargets]
{(
    
)}
(lldb) po [testButton actionsForTarget:(id)0x7fb2b670e2f0 forControlEvent:0]
<__NSArrayM 0x60800005c3b0>(
testButtonPressed:
)
复制代码

观察实例变量变化

后面跟变量地址

(lldb) watchpoint set e -- 0x0000600000228d40
复制代码

非重写方法符号断点

在子类中没有实现viewDidAppear方法,而是在父类中实现的,用breakpoint设置不可以,需要用Chisel中bmessage命令:

(lldb) bmessage -[WebpImageViewController viewDidAppear:]
Setting a breakpoint at -[UIViewController viewDidAppear:] with condition (void*)object_getClass((id)$rdi) == 0x000000010888aeb0
Breakpoint 2: where = UIKit`-[UIViewController viewDidAppear:], address = 0x000000010babd132
复制代码

参考文章

分类:
iOS
标签:
分类:
iOS
标签:
收藏成功!
已添加到「」, 点击更改