不用但一定要懂 ---- iOS 之 Xcode 中 LLDB调
2022-06-14 本文已影响0人
我来也super
LLDB全称Low Level Debugger ,并不是低水平的调试器,而是轻量级的高性能调试器,默认内置于Xcode中
一、 LLDB常用调试命令
1、p
和 po
:
p
是expr -
的缩写。它的工作是把接收到的参数在当前环境下进行编译,然后打印出对应的值。po
即expr -o-
。它所做的操作与p
相同。如果接收到的参数是一个指针,那么它会调用对象的description
方法并打印。如果接收到的参数是一个core foundation
对象,那么它会调用CFShow
方法并打印。如果这两个方法都调用失败,那么po
打印出和p
相同的内容。p
和po
命令都可以修改变量
总结来说,po
相对于 p
会打印出更多内容。一般在工作中,用 p
即可,因为 p
操作较少,效率更高。
2、image lookup
2.1 image lookup -address
查找崩溃位置
当你遇见数组崩溃,你又没有找到崩溃的位置,只扔给你一堆报错信息,这时候image lookup来帮助你。如下
执行image lookup -a 0x0000000100003f34
后:
Address: test[0x0000000100003f34] (test.__TEXT.__text + 68)
Summary: test`main + 68 at main.m:17:5
出现问题代码定位到 main.m:17:5 如下图:
2.2 image lookup -name
查找方法来源 or image lookup -n
此命令可以用来查找函数的来源。包括第三方SDK中的方法,也能被查到。
例:查找test_fun_1
(lldb) image lookup -n test_fun_1
1 match found in /Users/supersun/Library/Developer/Xcode/DerivedData/test-cbatanrpndbntadolhjkfjihrkms/Build/Products/Debug/test:
Address: test[0x0000000100003c70] (test.__TEXT.__text + 0)
Summary: test`+[calssTest test_fun_1] at calssTest.m:12
被查找的函数必须是实现方法,包含类函数和实例函数,只声明函数而不实现则查找不到。
2.3 image lookup -type
查看成员 or image lookup -t
查看某个class的所有属性和成员变量。framework库中的文件不能查看。
(lldb) image lookup -t calssTest
Best match found in /Users/supersun/Library/Developer/Xcode/DerivedData/test-cbatanrpndbntadolhjkfjihrkms/Build/Products/Debug/test:
id = {0x100000033}, name = "calssTest", byte-size = 32, decl = calssTest.h:12, compiler_type = "@interface calssTest : NSObject{
NSString * _property_1;
NSDictionary * _property_2;
NSArray * _property_3;
}
@property(nonatomic, readwrite, getter = property_1, setter = setProperty_1:) NSString *property_1;
@property(nonatomic, readwrite, getter = property_2, setter = setProperty_2:) NSDictionary *property_2;
@property(nonatomic, readwrite, getter = property_3, setter = setProperty_3:) NSArray *property_3;
@end"
3、bt
和 frame select
:
3.1 bt
命令查看函数调用栈
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = step over
* frame #0: 0x0000000100003c2e test`-[calssTest hello](self=0x0000000101030e50, _cmd="hello") at calssTest.m:28:1
frame #1: 0x0000000100003bff test`-[calssTest login_success](self=0x0000000101030e50, _cmd="login_success") at calssTest.m:23:5
frame #2: 0x0000000100003bbf test`-[calssTest login](self=0x0000000101030e50, _cmd="login") at calssTest.m:18:5
frame #3: 0x0000000100003b81 test`-[calssTest test_fun_1](self=0x0000000101030e50, _cmd="test_fun_1") at calssTest.m:13:5
frame #4: 0x0000000100003dc0 test`main(argc=1, argv=0x00007ff7bfeff420) at main.m:14:9
frame #5: 0x000000010001951e dyld`start + 462
(lldb)
bt
显示的是当前线程函数调用的信息,bt all
显示所有线程的堆栈信息
3.2 frame select
命令查看当前断点函数详细内容
(lldb) frame select
frame #0: 0x0000000100003be0 test`-[calssTest login_success](self=0x00000001013062a0, _cmd="login_success") at calssTest.m:22:5
19 }
20
21 -(void)login_success{
-> 22 NSLog(@"login_success");
^
23 [self hello];
24 }
25
(lldb)
同时配合up
和 down
命令追中函数调用和被调用的关系
(lldb) up
frame #1: 0x0000000100003bbf test`-[calssTest login](self=0x00000001012491d0, _cmd="login") at calssTest.m:18:5
15
16 -(void)login{
17 NSLog(@"login");
-> 18 [self login_success];
^
19 }
3.3 frame variable
可查看函数调用者和函数名称
(lldb) frame variable
(calssTest *) self = 0x00000001012491d0 //函数调用者
(SEL) _cmd = "login_success" //函数名称
(lldb)
4、Breakpoint
直接用写命令的方式打断点、调试、编辑断点信息。
b 某文件.m:30
给某文件的第30行打个断点br l
列出当前工程的所有断点信息br delete n
删除第n个断点br enable n
使第n个断点有效br disable n
使第n个断点失效br set -n 某方法
设置关于这个方法的符号断点,在调用这个方式时,程序都会暂停br mod -c "某文件" n
设置条件断点
- Continue 简称
c
断点继续执行 直接输入在lldb控制台上- stepOver 简称
n
一步一步执行方法- stepInto 简称
s
进入方法调用里面- stepOut 简称
finish
跳出方法调用
5、Thread
可以操作线程,显示当前线程信息,在运行时,直接改变方法调用的返回值
thread list
显示所有线程信息thread select n
选择第n个线程thread backtrace
显示当前thread的堆栈信息thread backtrace all
显示所有thread的堆栈信息thread until i
使线程运行,并在第i行时停下thread return
返回值 直接改变当前方法调用的返回值