lldb(Low Lever Debug):默認(rèn)內(nèi)置于Xcode中的動(dòng)態(tài)調(diào)試工具。標(biāo)準(zhǔn)的lldb提供了一組廣泛的命令,旨在與老版本的GDB命令兼容。 除了使用標(biāo)準(zhǔn)配置外,還可以很容易地自定義lldb以滿足實(shí)際需要
lldb語法:<command> [<subcommand> [<subcommand>...]] <action> [-options [option-value]] [argument [argument...]]
<command>(命令)和<subcommand>(子命令):lldb調(diào)試命令的名稱<action>:執(zhí)行命令的操作<options>:命令選項(xiàng)<arguement>:命令的參數(shù)[]:表示命令是可選的,可以有也可以沒有示例:
breakpoint set -n test
command:breakpoint表示斷點(diǎn)命令action:set表示設(shè)置斷點(diǎn)option:-n表示根據(jù)方法name設(shè)置斷點(diǎn)arguement:test表示方法名為tset
斷點(diǎn)設(shè)置
日常開發(fā)中,最常用的是
Xcode斷點(diǎn)
但是在逆向環(huán)境中,我們并沒有第三方應(yīng)用的源碼,也不可能通過界面設(shè)置斷點(diǎn)
這種情況,只能使用
breakpoint指令,在Xcode中lldb控制臺(tái),或直接在終端進(jìn)行斷點(diǎn)設(shè)置
案例1:
breakpoint指令的使用打開
ViewController.m文件,寫入以下代碼:#import "ViewController.h" @implementation ViewController void test1(){ NSLog(@"3"); } - (void)viewDidLoad { [super viewDidLoad]; } -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { NSLog(@"1"); NSLog(@"2"); test1(); } @end對(duì)
test1函數(shù)設(shè)置斷點(diǎn)breakpoint set -n test1 ------------------------- Breakpoint 2: where = 001--LLDB調(diào)試`test1 + 16 at ViewController.m:13:5, >address = 0x0000000102ef1cb4
- 對(duì)符號(hào)設(shè)置斷點(diǎn)
set是子命令-n是選項(xiàng),是--name的縮寫- 顯示
Breakpoint 2,說明在001--LLDB調(diào)試的進(jìn)程中,設(shè)置的第2個(gè)斷點(diǎn),第1個(gè)是使用Xcode在touchesBegan中設(shè)置的
案例2:
對(duì)控制器的指定方法設(shè)置斷點(diǎn)
打開
ViewController.m文件,寫入以下代碼:#import "ViewController.h" @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; } - (IBAction)save:(id)sender { NSLog(@"保存"); } - (IBAction)pause:(id)sender { NSLog(@"暫停"); } - (IBAction)continueGame:(id)sender { NSLog(@"繼續(xù)"); } @end在逆向環(huán)境中,運(yùn)行第三方程序,使用暫??蛇M(jìn)入
lldb控制臺(tái),相當(dāng)于Debug進(jìn)程附加
對(duì)
ViewController中的多個(gè)符號(hào)設(shè)置斷點(diǎn)breakpoint set -n "-[ViewController save:]" -n "-[ViewController pause:]" -n "-[ViewController continueGame:]" ------------------------- Breakpoint 1: 3 locations.
Breakpoint 1表示分組13 locations表示分組1下設(shè)置了3個(gè)斷點(diǎn)使用
breakpoint list查看斷點(diǎn)breakpoint list ------------------------- Current breakpoints: 1: names = {'-[ViewController save:]', '-[ViewController pause:]', '-[ViewController continueGame:]'}, locations = 3, resolved = 3, hit count = 0 1.1: where = 001--LLDB調(diào)試`-[ViewController save:] + 60 at ViewController.m:17:5, address = 0x0000000104995cd0, resolved, hit count = 0 1.2: where = 001--LLDB調(diào)試`-[ViewController pause:] + 60 at ViewController.m:21:5, address = 0x0000000104995d28, resolved, hit count = 0 1.3: where = 001--LLDB調(diào)試`-[ViewController continueGame:] + 60 at ViewController.m:25:5, address = 0x0000000104995d80, resolved, hit count = 0
案例3:
斷點(diǎn)的禁用、啟動(dòng)和刪除
禁用斷點(diǎn)
breakpoint disable 1 ------------------------- 1 breakpoints disabled.
- 將
分組1下的所有斷點(diǎn)禁用啟用斷點(diǎn)
breakpoint enable 1 ------------------------- 1 breakpoints enabled.
- 將
分組1下的所有斷點(diǎn)啟用也可以對(duì)單一斷點(diǎn)禁用或啟用,例如:
breakpoint disable 1.1 ------------------------- 1 breakpoints disabled.刪除
分組1下的所有斷點(diǎn)breakpoint delete 1 ------------------------- 1 breakpoints deleted; 0 breakpoint locations disabled.刪除全部斷點(diǎn)
breakpoint delete ------------------------- About to delete all breakpoints, do you want to do that?: [Y/n] y All breakpoints removed. (1 breakpoint)不支持刪除某單一斷點(diǎn),例如:
breakpoint delete 4.1 ------------------------- 0 breakpoints deleted; 1 breakpoint locations disabled.
案例4:
了解更多
breakpoint指令使用
help指令help breakpoint ------------------------- Commands for operating on breakpoints (see 'help b' for shorthand.) Syntax: breakpoint <subcommand> [<command-options>] The following subcommands are supported: clear -- Delete or disable breakpoints matching the specified source file and line. command -- Commands for adding, removing and listing LLDB commands executed when a breakpoint is hit. delete -- Delete the specified breakpoint(s). If no breakpoints are specified, delete them all. disable -- Disable the specified breakpoint(s) without deleting them. If none are specified, disable all breakpoints. enable -- Enable the specified disabled breakpoint(s). If no breakpoints are specified, enable all of them. list -- List some or all breakpoints at configurable levels of detail. modify -- Modify the options on a breakpoint or set of breakpoints in the executable. If no breakpoint is specified, acts on the last created breakpoint. With the exception of -e, -d and -i, passing an empty argument clears the modification. name -- Commands to manage name tags for breakpoints read -- Read and set the breakpoints previously saved to a file with "breakpoint write". set -- Sets a breakpoint or set of breakpoints in the executable. write -- Write the breakpoints listed to a file that can be read in with "breakpoint read". If given no arguments, writes all breakpoints. For more help on any particular subcommand, type 'help <command> <subcommand>'.也可以了解更多選項(xiàng)的參數(shù)設(shè)置,例如:
help breakpoint set ------------------------- Sets a breakpoint or set of breakpoints in the executable. Syntax: breakpoint set <cmd-options> Command Options Usage: breakpoint set [-DHd] -l <linenum> [-G <boolean>] [-C <command>] [-c <expr>] [-i <count>] [-o <boolean>] [-q <queue-name>] [-t <thread-id>] [-x <thread-index>] [-T <thread-name>] [-R <address>] [-N <breakpoint-name>] [-u <column>] [-f <filename>] [-m <boolean>] [-s <shlib-name>] [-K <boolean>] breakpoint set [-DHd] -a <address-expression> [-G <boolean>] [-C <command>] [-c <expr>] [-i <count>] [-o <boolean>] [-q <queue-name>] [-t <thread-id>] [-x <thread-index>] [-T <thread-name>] [-N <breakpoint-name>] [-s <shlib-name>] ...
案例5:
對(duì)包含字符串的符號(hào)設(shè)置斷點(diǎn)
使用
breakpoint set -n,對(duì)touchesBegan方法設(shè)置斷點(diǎn)breakpoint set -n touchesBegan: ------------------------- Breakpoint 5: no locations (pending). WARNING: Unable to resolve breakpoint to any actual locations.
- 并沒有設(shè)置上斷點(diǎn),因?yàn)橥暾姆?hào)為
touchesBegan:withEvent:使用
breakpoint set -r,對(duì)包含touchesBegan的符號(hào)設(shè)置斷點(diǎn)breakpoint set -r touchesBegan: ------------------------- Breakpoint 7: 101 locations.使用
breakpoint set --selector,對(duì)項(xiàng)目內(nèi)指定名稱的selector設(shè)置斷點(diǎn)breakpoint set --selector touchesBegan:withEvent: ------------------------- Breakpoint 9: 96 locations.
案例6:
指定文件設(shè)置斷點(diǎn)
使用
breakpoint set --file,在指定文件內(nèi)設(shè)置斷點(diǎn)breakpoint set --file ViewController.m --selector touchesBegan:withEvent: ------------------------- Breakpoint 2: where = 001--LLDB調(diào)試`-[ViewController touchesBegan:withEvent:] + 92 at ViewController.m:30:4, address = 0x0000000100745d44
案例7:
lldb強(qiáng)大的縮寫功能對(duì)包含
touchesBegan的符號(hào)設(shè)置斷點(diǎn)b -r touchesBegan ------------------------- Breakpoint 3: 105 locations.查看斷點(diǎn)的列表
break list更簡單的寫法:
br list對(duì)禁用斷點(diǎn)
disable選項(xiàng)的簡寫:br dis 1 ------------------------- 1 breakpoints disabled.對(duì)啟用斷點(diǎn)
enable選項(xiàng)的簡寫:br en 1 ------------------------- 1 breakpoints enabled.
代碼執(zhí)行
expression指令,用于執(zhí)行代碼,縮寫指令為p、exp配合
p指令使用的po指令,意思是print object,用于打印對(duì)象,本質(zhì)上調(diào)用了對(duì)象的description
案例1:
使用
expression指令執(zhí)行代碼對(duì)
ViewController中的touchesBegan設(shè)置斷點(diǎn)br set -f ViewController.m -r touchesBegan ------------------------- Breakpoint 2: where = 001--LLDB調(diào)試`-[ViewController touchesBegan:withEvent:] + 92 at ViewController.m:30:4, address = 0x0000000102de5d44點(diǎn)擊屏幕,進(jìn)入斷點(diǎn),使用
expression指令執(zhí)行代碼expression self.view.subviews ------------------------- (__NSArrayM *) $0 = 0x00000002822eaee0 @"3 elements"
案例2:
設(shè)置背景色
使用
expression指令,設(shè)置self.view的背景色expression self.view.backgroundColor = [UIColor redColor] ------------------------- error: <user expression 16>:1:11: property 'backgroundColor' not found on object of type 'UIView *'
- 報(bào)錯(cuò),無法直接修改
backgroundColor屬性換一種方式,修改
layer下的backgroundColor屬性expression self.view.layer.backgroundColor = [UIColor yellowColor].CGColor ------------------------- (CGColorRef) $7 = 0x00000002808a0d20
案例3:
對(duì)數(shù)組追加元素
打開
ViewController.m文件,寫入以下代碼:#import "ViewController.h" #import "Person.h" @interface ViewController () @property(nonatomic, strong) NSMutableArray<Person *> * models; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; Person * p1 = [[Person alloc] initWithName:@"one" age:1]; Person * p2 = [[Person alloc] initWithName:@"two" age:2]; Person * p3 = [[Person alloc] initWithName:@"three" age:3]; [self.models addObject:p1]; [self.models addObject:p2]; [self.models addObject:p3]; } -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { NSLog(@"models:%@",self.models); } -(NSMutableArray<Person *> *)models { if (!_models) { _models = [NSMutableArray array]; } return _models; } @end對(duì)
ViewController中的touchesBegan設(shè)置斷點(diǎn)br set -f ViewController.m -r touchesBegan ------------------------- Breakpoint 1: where = 001--LLDB調(diào)試`-[ViewController touchesBegan:withEvent:] + 84 at ViewController.m:33:25, address = 0x0000000100cc5a6c點(diǎn)擊屏幕,進(jìn)入
touchesBegan方法的斷點(diǎn),追加數(shù)組元素p [self.models addObject:[[Person alloc] initWithName:@"haha" age:4]]使用
c(continue)指令,繼續(xù)執(zhí)行c ------------------------- 001--LLDB調(diào)試[12107:2333568] models:( "<Person: 0x281043640>", "<Person: 0x281043680>", "<Person: 0x2810436a0>", "<Person: 0x2810591e0>" )輸出的
models數(shù)組中存儲(chǔ)了4個(gè)對(duì)象,元素追加成功
案例4:
修改數(shù)組中對(duì)象的屬性
點(diǎn)擊屏幕,進(jìn)入
touchesBegan方法的斷點(diǎn),獲取數(shù)組的第一個(gè)元素p (Person *)self.models.firstObject ------------------------- (Person *) $4 = 0x0000000281043640
$4為標(biāo)號(hào),代表Person對(duì)象,可以使用使用標(biāo)號(hào),修改對(duì)象
name屬性p $4.name=@"123" ------------------------- (NSTaggedPointerString *) $5 = 0xb868e91f5b072f35 @"123"驗(yàn)證
name屬性是否修改成功po self.models.firstObject ------------------------- <Person: 0x281043640>p ((Person *)0x281043640).name ------------------------- (NSTaggedPointerString *) $10 = 0xb868e91f5b072f35 @"123"
案例5:
執(zhí)行多行代碼
點(diǎn)擊屏幕,進(jìn)入
touchesBegan方法的斷點(diǎn)通過
Option+Enter進(jìn)行換行,在lldb控制臺(tái)寫入以下代碼:p Person * $tmp = self.models.firstObject; p $tmp.name = @"Zang"; p $tmp.age = 18; ------------------------- (NSTaggedPointerString *) $6 = 0x996ea49769521a4e @"Zang" (int) $7 = 18
案例6:
其他流程控制的指令
使用
c(continue)指令,繼續(xù)執(zhí)行c使用
n(next)指令,單步運(yùn)行,將子函數(shù)當(dāng)做整體一步執(zhí)行n使用
s指令,單步運(yùn)行,遇到子函數(shù)會(huì)進(jìn)去s
堆棧信息
案例1:
查看函數(shù)調(diào)用棧
使用
bt指令,查看函數(shù)調(diào)用棧
*指向當(dāng)前的函數(shù)調(diào)用棧使用
up指令,查看上一個(gè)函數(shù)up ------------------------- frame #1: 0x0000000100151c68 001--LLDB調(diào)試`test1 at >ViewController.m:22:5 19 } 20 21 void test1(){ -> 22 test2(); ^ 23 } 24 25 void test2(){同時(shí)
*也指向上一個(gè)函數(shù)
使用
down指令,查看下一個(gè)函數(shù)down ------------------------- frame #0: 0x0000000100151c80 001--LLDB調(diào)試`test2 at >ViewController.m:26:4 23 } 24 25 void test2(){ -> 26 NSLog(@"test2"); ^ 27 } 28 29 @end使用
frame select指令,選擇指定函數(shù)frame select 10 ------------------------- frame #10: 0x000000019ef67480 UIKitCore`__eventFetcherSourceCallback + 156 UIKitCore`__eventFetcherSourceCallback: -> 0x19ef67480 <+156>: ldr x0, [x19, #0x10] 0x19ef67484 <+160>: mov x1, x21 0x19ef67488 <+164>: bl 0x19c2d1e28 0x19ef6748c <+168>: mov x1, x0使用上述指令,可以將斷點(diǎn)定位到指定函數(shù)。它的作用可以查看函數(shù)的調(diào)用者,通過匯編代碼分析參數(shù)的傳遞。但寄存器的環(huán)境并不會(huì)發(fā)生變化,數(shù)據(jù)保存的還是最后一個(gè)函數(shù)執(zhí)行完畢的結(jié)果
案例2:
查看方法的參數(shù)和局部變量
打開
ViewController.m文件,寫入以下代碼:#import "ViewController.h" @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; } -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { [self lalala1:@"HAHA"]; } -(void)lalala1:(NSString *)str{ [self lalala2:str]; } -(void)lalala2:(NSString *)str{ NSString *str1 = @"Zang"; NSLog(@"%@:%@",str1, str); } @end點(diǎn)擊屏幕,進(jìn)入
lalala2方法的斷點(diǎn),使用frame variable指令,查看方法的參數(shù)和局部變量frame variable ------------------------- (ViewController *) self = 0x0000000105506860 (SEL) _cmd = "lalala2:" (__NSCFConstantString *) str = 0x0000000104f94080 @"HAHA" (__NSCFConstantString *) str1 = 0x0000000104f940a0 @"Zang"在逆向過程中,進(jìn)入一個(gè)方法,最想看到的就是該方法的調(diào)用者、方法名稱、參數(shù)等信息,我們可以使用
frame variable指令進(jìn)行查看。還可以配合up、down、frame select指令,查看調(diào)用棧中其他方法的信息
案例3:
修改方法的參數(shù)
上述案例,點(diǎn)擊屏幕,進(jìn)入
lalala2方法的斷點(diǎn)使用
frame variable指令,查看方法的參數(shù)和局部變量frame variable ------------------------- (ViewController *) self = 0x0000000100708b60 (SEL) _cmd = "lalala2:" (__NSCFConstantString *) str = 0x0000000100124080 @"HAHA" (__NSCFConstantString *) str1 = 0x00000001001240a0 @"Zang"使用
p指令,修改str的值p str = @"COOL" ------------------------- (NSTaggedPointerString *) $0 = 0xb4f673513386c4f4 @"COOL"使用
c指令,繼續(xù)運(yùn)行c ------------------------- 001--LLDB調(diào)試[13539:2617881] Zang:COOL輸出結(jié)果變?yōu)樾薷暮蟮膬?nèi)容,只針對(duì)當(dāng)前未執(zhí)行完的方法有效。對(duì)于已經(jīng)執(zhí)行完的方法,修改里面的內(nèi)容,并不影響最終的結(jié)果
案例4:
讓方法直接返回,不執(zhí)行里面的代碼
打開
ViewController.m文件,寫入以下代碼:#import "ViewController.h" @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; } -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { [self check:@"HOOK"]; NSLog(@"一切正常~"); } -(void)check:(NSString *)str{ if([str isEqualToString:@"HOOK"]){ NSLog(@"有人HOOK我..."); exit(0); } } @end點(diǎn)擊屏幕,進(jìn)入
check方法的斷點(diǎn)使用
thread return指令,讓check方法直接返回,不執(zhí)行里面的代碼thread return使用
frame variable指令,查看thread return指令執(zhí)行后的函數(shù)frame variable ------------------------- (ViewController *) self = 0x0000000100e07ee0 (SEL) _cmd = "touchesBegan:withEvent:" (__NSSetM *) touches = 0x0000000283e4dbc0 1 element (UITouchesEvent *) event = 0x0000000280b61200
- 已經(jīng)回到
touchesBegan:withEvent:方法使用
c指令,繼續(xù)運(yùn)行c ------------------------- 001--LLDB調(diào)試[13574:2625998] 一切正常~
check方法直接返回,方法內(nèi)驗(yàn)證str參數(shù)的代碼沒有被觸發(fā)
thread return指令,可用于調(diào)試階段,繞過指定方法使用場景:原本執(zhí)行到某方法,執(zhí)行就會(huì)中斷。使用
thread return指令繞過方法,如果可以正常執(zhí)行,證明此方法為檢測方法。后續(xù)可針對(duì)不同情況,選擇Method Swizzle、fishHook、InlineHook對(duì)其進(jìn)行HOOK,將方法直接return
內(nèi)存斷點(diǎn)
案例1:
在對(duì)象的屬性上設(shè)置斷點(diǎn)
對(duì)
p1修改name屬性時(shí),設(shè)置斷點(diǎn)
進(jìn)入斷點(diǎn),使用
watchpoint指令,在p1對(duì)象的name上設(shè)置斷點(diǎn)watchpoint set variable p1->_name ------------------------- Watchpoint created: Watchpoint 1: addr = 0x280207570 size = 8 state = enabled type = w declare @ '/Users/zang/Zang/Spark/LG/14/LLDB/001--LLDB調(diào)試/ViewController.m:13' watchpoint spec = 'p1->_name' new value: 0x0000000102404088使用
c指令,繼續(xù)運(yùn)行c ------------------------- Watchpoint 1 hit: old value: 0x0000000102404088 new value: 0x00000001024040a8使用
po指令po 0x0000000102404088 ------------------------- onepo 0x00000001024040a8 ------------------------- new當(dāng)調(diào)用
name屬性的get/set方法,都會(huì)觸發(fā)此斷點(diǎn)。可獲取到name屬性的原始值,和即將修改的值。配合bt指令,查看函數(shù)調(diào)用棧,可以跟蹤name屬性的修改是由哪個(gè)方法觸發(fā)的
案例2:
對(duì)屬性地址設(shè)置內(nèi)存斷點(diǎn)
進(jìn)入斷點(diǎn),獲取
name屬性的地址p &p1->_name ------------------------- (NSString **) $0 = 0x0000000281e2ebb0使用
watchpoint指令,對(duì)屬性地址設(shè)置內(nèi)存斷點(diǎn)watchpoint set expression 0x0000000281e2ebb0 ------------------------- Watchpoint created: Watchpoint 1: addr = 0x281e2ebb0 size = 8 state = enabled type = w new value: 4371808392使用
c指令,繼續(xù)運(yùn)行c ------------------------- Watchpoint 1 hit: old value: 4371808392 new value: 4371808424使用
po指令po 4371808392 ------------------------- onepo 4371808424 ------------------------- new
其他指令
案例1:
當(dāng)分組下斷點(diǎn)被觸發(fā),自動(dòng)執(zhí)行指令
在
touchesBegan方法設(shè)置斷點(diǎn)br set -f ViewController.m -r touchesBegan: ------------------------- Breakpoint 3: where = 001--LLDB調(diào)試`-[ViewController touchesBegan:withEvent:] + 84 at ViewController.m:20:26, address = 0x0000000104945a6c對(duì)
分組3斷點(diǎn),設(shè)置進(jìn)入斷點(diǎn)后的執(zhí)行的指令br command add 3 ------------------------- Enter your debugger command(s). Type 'DONE' to end. >輸入指令
> frame variable > DONE使用
c指令,繼續(xù)運(yùn)行c點(diǎn)擊屏幕,進(jìn)入
touchesBegan方法的斷點(diǎn),同時(shí)輸出以下信息:frame variable (ViewController *) self = 0x0000000103507fc0 (SEL) _cmd = "touchesBegan:withEvent:" (__NSSetM *) touches = 0x0000000282cea2e0 1 element (UITouchesEvent *) event = 0x00000002819c6640 (Person *) p1 = 0x00000001e3fe2f18
案例2:
當(dāng)任何斷點(diǎn)被觸發(fā),自動(dòng)執(zhí)行指令
target stop-hook add -o "frame variable" ------------------------- Stop hook #1 added.查看
stop-hook的指令列表target stop-hook list ------------------------- Hook: 1 State: enabled Commands: frame variable刪除某一條指令
target stop-hook delete 1undisplay 1刪除全部指令
target stop-hook delete ------------------------- Delete all stop hooks?: [Y/n] y禁用某一條指令
target stop-hook disable 1啟用某一條指令
target stop-hook enable 1添加執(zhí)行代碼
display self.view
- 等同于
expr -- self.view對(duì)于
frame variable指令,基本上每個(gè)斷點(diǎn)觸發(fā)后都要使用。但lldb每次啟動(dòng)都要重新配置命令,有沒有一勞永逸的方法呢?
案例3:
配置
lldb初始化文件在家目錄下,存儲(chǔ)了
lldb的初始化文件cd / ls
lldbinit文件的作用,當(dāng)lldb啟動(dòng),就會(huì)加載此文件,執(zhí)行文件內(nèi)的指令使用
vi ~/.lldbinit,寫入以下指令:target stop-hook add -o "frame variable"運(yùn)行項(xiàng)目,
lldb啟動(dòng),輸出以下內(nèi)容:Stop hook #1 added.進(jìn)入
viewDidLoad斷點(diǎn),輸出以下內(nèi)容:(ViewController *) self = 0x0000000135f093a0 (SEL) _cmd = "viewDidLoad"
總結(jié)
斷點(diǎn)設(shè)置
breakpoint set -n xxx:對(duì)方法/函數(shù)名稱設(shè)置斷點(diǎn)breakpoint set -r xxx:對(duì)包含字符串的符號(hào)設(shè)置斷點(diǎn)breakpoint set --selector xxx:對(duì)項(xiàng)目內(nèi)指定名稱的selector設(shè)置斷點(diǎn)breakpoint set --file xxx:在指定文件中設(shè)置斷點(diǎn)breakpoint list:查看斷點(diǎn)列表breakpoint disable:禁用斷點(diǎn)breakpoint enable:啟用斷點(diǎn)breakpoint delete:刪除斷點(diǎn)- 縮寫:
break、br,設(shè)置斷點(diǎn)可縮寫指令:b代碼執(zhí)行
po指令:意思是print object,用于打印對(duì)象,本質(zhì)上調(diào)用了對(duì)象的descriptionexpression指令:用于執(zhí)行代碼
? 縮寫:exp、p
? 可以使用標(biāo)號(hào)
? 可執(zhí)行多行代碼- 流程控制
?c(continue)指令:繼續(xù)執(zhí)行
?n(next)指令:單步運(yùn)行,將子函數(shù)當(dāng)做整體一步執(zhí)行
?ni指令:單步運(yùn)行匯編級(jí)別
?s指令:單步運(yùn)行,遇到子函數(shù)會(huì)進(jìn)去
?si指令:單步運(yùn)行可跳轉(zhuǎn)指令內(nèi)部,匯編級(jí)別
?finish指令:直接走完當(dāng)前方法,返回到上層frame堆棧信息
bt指令:查看函數(shù)調(diào)用棧up指令:查看上一個(gè)函數(shù)down指令:查看下一個(gè)函數(shù)frame select指令:選擇指定函數(shù)frame variable指令:查看方法調(diào)用者、方法名稱、參數(shù)和局部變量thread return指令:讓方法直接返回,不執(zhí)行里面的代碼內(nèi)存斷點(diǎn):
watchpoint指令,設(shè)置內(nèi)存斷點(diǎn)其他指令
br command add指令:給斷點(diǎn)添加命令的命令target stop-hook add -o "xxx":每次stop的時(shí)候去執(zhí)行一些命令,針對(duì)breadpoint、watchpoint- 配置
lldb初始化文件,當(dāng)lldb啟動(dòng),就會(huì)加載此文件,執(zhí)行文件內(nèi)的指令,一勞永逸
lldb更多文檔





