配合LLDB調試器進行iOS代碼調試

配合LLDB調試器進行iOS代碼調試

        在一款完整iOS移動應用的開發中,代碼的調試和編寫佔着同等重要的地位。Xcode默認使用LLDB做爲代碼調試器,LLDB功能豐富且強大,恰當的使用它,能夠幫助開發者事半功倍的完成代碼調試的工做。express

1.expression代碼執行指令

        關於LLDB調試器,最經常使用的指令應該是p與po了,開發者經常使用這兩個命令來進行對象的打印操做,p會打印出對象地址和類型,po則會額外打印出對象的值得內容,實際上,這兩個命令都是expression相關命令的簡寫。expression命令也並不是簡單的打印命令,實際上它是一個執行代碼命令,執行後將返回值進行打印,這個命令有一個十分強大的特色,它能夠真實改變程序運行中變量的值。例如在以下代碼中的int c = a+b 一行添加一個斷點,運行工程。sass

    int a = 0;
    int b = 1;
    int c = a+b;
    NSLog(@"%d",c);

若是開發者不進行任何認爲操做,此時打印出的值應該是1,爲了測試,能夠在調試區輸入以下命令:app

(lldb) expression a=1

此後跳過斷點繼續運行程序,能夠看到打印的結果以下,c變成2。iphone

(lldb) expression a=1
(int) $0 = 1
2016-04-24 11:39:40.213 BreakPointTest[1010:79065] 2

經過上面的演示,咱們發現使用LLDB調試代碼十分方便的一個特色,當咱們知道程序某個地方可能會出現問題,爲了找到解決方法,不使用LLDB時咱們可能須要在代碼中添加大量的打印函數,而且屢次嘗試修改源代碼才能解決問題,若是使用LLDB的expression命令,咱們不只不須要添加額外的打印代碼,也不須要直接修改源代碼,在調試區進行屢次調試,直到找到正確的修改方法後再對源代碼修改一次便可。函數

2.frame代碼堆棧塊信息相關指令

      當Xcode進入斷點調試或者遇到異常程序崩潰時,在Xcode左側的導航區都會將程序運行中的相關堆棧塊信息列舉出來,例如使用以下測試代碼,在text方法中的int c = a+b 一行添加一個斷點。工具

#import "ViewController.h"
@interface ViewController ()
{
    int ab;
}
@end
@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    ab = 1;
    [self test];  
}
-(void)test{
    int a = 0;
    int b = 1;
    int c = a+b;
    NSLog(@"%d",c);
}
@end

當程序運行到斷點處斷開時,Xcode左側的堆棧塊以下圖所示:oop

從圖中能夠看出,程序當前處於激活狀態的線程有5個,程序目前斷在線程1中的test方法堆棧塊中,使用frame info指令能夠打印當前堆棧塊的信息,示例以下:學習

(lldb) frame info
frame #0: 0x0000000102497905 BreakPointTest`-[ViewController test](self=0x00007fcd5b413320, _cmd="test") + 37 at ViewController.m:39

在打印的信息中,會有所在的文件名稱和函數名稱及堆棧塊標號和內存地址。測試

      在實際代碼調試過程當中,程序運行的回溯是一個重要的方法,例如上面的代碼例子,雖然如今斷點斷在test方法中,開發者可能須要在viewDidLoad方法中進行相關調試,例如上面viewDidLoad方法中有一個變量ab,若是想查看ab變量的值,咱們就須要將當前選中調試的堆棧塊選擇爲viewDidLoad方法所在的堆棧塊,從Xcode左側導航區能夠看到,viewDidLoad方法堆棧塊的標號爲1,執行以下LLDB指令便可切換:ui

(lldb) frame select 1
frame #1: 0x00000001024978cb BreakPointTest`-[ViewController viewDidLoad](self=0x00007fcd5b413320, _cmd="viewDidLoad") + 91 at ViewController.m:31
   28  	    int a = 0;
   29  	    int b = 1;
   30  	    int c = a+b;
-> 31  	    NSLog(@"%d",c);
   32  	}
   33  	@end

從打印信息能夠看到,如今選中的調試堆棧塊已經切換到viewDidLoad方法,再使用expression指令時就能夠操做這個方法中的相關變量了。

      在使用LLDB工具前,遇到這樣的狀況,我每每會採用打多個斷點,一步步追溯代碼的運行過程並檢查過程當中變量的值是否正確,調試起來並不十分方便,若是不當心錯過了某個斷點,又要從新開始,經過選擇調試的frame堆棧塊能夠十分方便的解決這個問題。

      與frame相關的還有一個指令十分有用,下面的指令能夠打印出當前堆棧塊中全部對象的內容:

(lldb) frame variable
(ViewController *) self = 0x00007fcd5b413320
(SEL) _cmd = "test"
(int) a = 0
(int) b = 1
(int) c = 0

variable後面也能夠添加參數名來打印特定對象的內容:

(lldb) frame variable a
(int) a = 0

3.thread線程操做相關指令

      上面提到過,程序運行中會有多個激活的線程,每一個線程中又有許多堆棧塊,frame相關指令用於綜合調試各個堆棧塊,thread指令則是用於綜合調試各個線程。首先Xcode左側導航區爲咱們列出的線程堆棧塊並非當前線程中的全部堆棧塊,使用以下命令能夠打印出當前線程的全部堆棧塊:

(lldb) thread backtrace
* thread #1: tid = 0x152f8, 0x0000000102497905 BreakPointTest`-[ViewController test](self=0x00007fcd5b413320, _cmd="test") + 37 at ViewController.m:39, queue = 'com.apple.main-thread', stop reason = breakpoint 2.1
  * frame #0: 0x0000000102497905 BreakPointTest`-[ViewController test](self=0x00007fcd5b413320, _cmd="test") + 37 at ViewController.m:39
    frame #1: 0x00000001024978cb BreakPointTest`-[ViewController viewDidLoad](self=0x00007fcd5b413320, _cmd="viewDidLoad") + 91 at ViewController.m:31
    frame #2: 0x0000000103475984 UIKit`-[UIViewController loadViewIfRequired] + 1198
    frame #3: 0x0000000103475cd3 UIKit`-[UIViewController view] + 27
    frame #4: 0x000000010334bfb4 UIKit`-[UIWindow addRootViewControllerViewIfPossible] + 61
    frame #5: 0x000000010334c69d UIKit`-[UIWindow _setHidden:forced:] + 282
    frame #6: 0x000000010335e180 UIKit`-[UIWindow makeKeyAndVisible] + 42
    frame #7: 0x00000001032d2ed9 UIKit`-[UIApplication _callInitializationDelegatesForMainScene:transitionContext:] + 4131
    frame #8: 0x00000001032d9568 UIKit`-[UIApplication _runWithMainScene:transitionContext:completion:] + 1769
    frame #9: 0x00000001032d6714 UIKit`-[UIApplication workspaceDidEndTransaction:] + 188
    frame #10: 0x0000000105d438c8 FrontBoardServices`__FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__ + 24
    frame #11: 0x0000000105d43741 FrontBoardServices`-[FBSSerialQueue _performNext] + 178
    frame #12: 0x0000000105d43aca FrontBoardServices`-[FBSSerialQueue _performNextFromRunLoopSource] + 45
    frame #13: 0x0000000102e4a301 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
    frame #14: 0x0000000102e4022c CoreFoundation`__CFRunLoopDoSources0 + 556
    frame #15: 0x0000000102e3f6e3 CoreFoundation`__CFRunLoopRun + 867
    frame #16: 0x0000000102e3f0f8 CoreFoundation`CFRunLoopRunSpecific + 488
    frame #17: 0x00000001032d5f21 UIKit`-[UIApplication _run] + 402
    frame #18: 0x00000001032daf09 UIKit`UIApplicationMain + 171
    frame #19: 0x0000000102497c3f BreakPointTest`main(argc=1, argv=0x00007fff5d768668) + 111 at main.m:14
    frame #20: 0x00000001056fe92d libdyld.dylib`start + 1
    frame #21: 0x00000001056fe92d libdyld.dylib`start + 1

thread list指令則能夠打印出當前全部激活的線程,以下:

(lldb) thread list
Process 1049 stopped
* thread #1: tid = 0x152f8, 0x0000000102497905 BreakPointTest`-[ViewController test](self=0x00007fcd5b413320, _cmd="test") + 37 at ViewController.m:39, queue = 'com.apple.main-thread', stop reason = breakpoint 2.1
  thread #2: tid = 0x1531b, 0x0000000105a43ee2 libsystem_kernel.dylib`kevent64 + 10, queue = 'com.apple.libdispatch-manager'
  thread #3: tid = 0x1531c, 0x0000000105a435e2 libsystem_kernel.dylib`__workq_kernreturn + 10
  thread #4: tid = 0x15324, 0x0000000105a435e2 libsystem_kernel.dylib`__workq_kernreturn + 10
  thread #5: tid = 0x15328, 0x0000000105a435e2 libsystem_kernel.dylib`__workq_kernreturn + 10

thread info能夠打印出當前選中調試的線程的信息:

(lldb) thread info
thread #1: tid = 0x152f8, 0x0000000102497905 BreakPointTest`-[ViewController test](self=0x00007fcd5b413320, _cmd="test") + 37 at ViewController.m:39, queue = 'com.apple.main-thread', stop reason = breakpoint 2.1

一樣也能夠使用thread select指令來切換選中調試的線程:

(lldb) thread select 2

thread continue指令用於繼續執行當前的線程:

(lldb) thread continue
2016-04-24 12:29:54.562 BreakPointTest[1049:86776] 1
Resuming thread 0x152f8 in process 1049
Process 1049 resuming

4.disassemble代碼反彙編相關指令

      disassemble相關指令用於輸出某段程序的彙編代碼,執行disassemble指令將會反彙編當前函數:

BreakPointTest`-[ViewController test]:
    0x10aab7940 <+0>:  pushq  %rbp
    0x10aab7941 <+1>:  movq   %rsp, %rbp
    0x10aab7944 <+4>:  subq   $0x20, %rsp
    0x10aab7948 <+8>:  leaq   0x1711(%rip), %rax        ; @"%d"
    0x10aab794f <+15>: movq   %rdi, -0x8(%rbp)
    0x10aab7953 <+19>: movq   %rsi, -0x10(%rbp)
    0x10aab7957 <+23>: movl   $0x0, -0x14(%rbp)
    0x10aab795e <+30>: movl   $0x1, -0x18(%rbp)
->  0x10aab7965 <+37>: movl   -0x14(%rbp), %ecx
    0x10aab7968 <+40>: addl   -0x18(%rbp), %ecx
    0x10aab796b <+43>: movl   %ecx, -0x1c(%rbp)
    0x10aab796e <+46>: movl   -0x1c(%rbp), %esi
    0x10aab7971 <+49>: movq   %rax, %rdi
    0x10aab7974 <+52>: movb   $0x0, %al
    0x10aab7976 <+54>: callq  0x10aab7c80               ; symbol stub for: NSLog
    0x10aab797b <+59>: addq   $0x20, %rsp
    0x10aab797f <+63>: popq   %rbp
    0x10aab7980 <+64>: retq

     使用disassemble -b則會輸出帶字節信息的彙編代碼:

(lldb) disassemble -b
BreakPointTest`-[ViewController test]:
    0x10aab7940 <+0>:  55                    pushq  %rbp
    0x10aab7941 <+1>:  48 89 e5              movq   %rsp, %rbp
    0x10aab7944 <+4>:  48 83 ec 20           subq   $0x20, %rsp
    0x10aab7948 <+8>:  48 8d 05 11 17 00 00  leaq   0x1711(%rip), %rax        ; @"%d"
    0x10aab794f <+15>: 48 89 7d f8           movq   %rdi, -0x8(%rbp)
    0x10aab7953 <+19>: 48 89 75 f0           movq   %rsi, -0x10(%rbp)
    0x10aab7957 <+23>: c7 45 ec 00 00 00 00  movl   $0x0, -0x14(%rbp)
    0x10aab795e <+30>: c7 45 e8 01 00 00 00  movl   $0x1, -0x18(%rbp)
->  0x10aab7965 <+37>: 8b 4d ec              movl   -0x14(%rbp), %ecx
    0x10aab7968 <+40>: 03 4d e8              addl   -0x18(%rbp), %ecx
    0x10aab796b <+43>: 89 4d e4              movl   %ecx, -0x1c(%rbp)
    0x10aab796e <+46>: 8b 75 e4              movl   -0x1c(%rbp), %esi
    0x10aab7971 <+49>: 48 89 c7              movq   %rax, %rdi
    0x10aab7974 <+52>: b0 00                 movb   $0x0, %al
    0x10aab7976 <+54>: e8 05 03 00 00        callq  0x10aab7c80               ; symbol stub for: NSLog
    0x10aab797b <+59>: 48 83 c4 20           addq   $0x20, %rsp
    0x10aab797f <+63>: 5d                    popq   %rbp
    0x10aab7980 <+64>: c3                    retq

      使用disassemble -c 指令能夠設置輸出彙編代碼的行數,以下:

(lldb) disassemble -c 5
BreakPointTest`-[ViewController test]:
    0x10aab7940 <+0>:  pushq  %rbp
    0x10aab7941 <+1>:  movq   %rsp, %rbp
    0x10aab7944 <+4>:  subq   $0x20, %rsp
    0x10aab7948 <+8>:  leaq   0x1711(%rip), %rax        ; @"%d"
    0x10aab794f <+15>: movq   %rdi, -0x8(%rbp)

      使用disassemble -l只輸出當前斷點處彙編代碼:

BreakPointTest`-[ViewController test] + 37 at ViewController.m:30
   29  	    int b = 1;
-> 30  	    int c = a+b;
   31  	    NSLog(@"%d",c);
BreakPointTest`-[ViewController test]:
->  0x10aab7965 <+37>: movl   -0x14(%rbp), %ecx

      使用disassemble -m混合顯示彙編代碼:

(lldb) disassemble -m
BreakPointTest`-[ViewController test] at ViewController.m:27
   26  	}
   27  	-(void)test{
   28  	    int a = 0;
BreakPointTest`-[ViewController test]:
    0x10aab7940 <+0>:  pushq  %rbp
    0x10aab7941 <+1>:  movq   %rsp, %rbp
    0x10aab7944 <+4>:  subq   $0x20, %rsp
    0x10aab7948 <+8>:  leaq   0x1711(%rip), %rax        ; @"%d"
    0x10aab794f <+15>: movq   %rdi, -0x8(%rbp)
    0x10aab7953 <+19>: movq   %rsi, -0x10(%rbp)
BreakPointTest`-[ViewController test] + 23 at ViewController.m:28
   27  	-(void)test{
   28  	    int a = 0;
   29  	    int b = 1;
    0x10aab7957 <+23>: movl   $0x0, -0x14(%rbp)
BreakPointTest`-[ViewController test] + 30 at ViewController.m:29
   28  	    int a = 0;
   29  	    int b = 1;
   30  	    int c = a+b;
    0x10aab795e <+30>: movl   $0x1, -0x18(%rbp)
BreakPointTest`-[ViewController test] + 37 at ViewController.m:30
   29  	    int b = 1;
-> 30  	    int c = a+b;
   31  	    NSLog(@"%d",c);
->  0x10aab7965 <+37>: movl   -0x14(%rbp), %ecx
BreakPointTest`-[ViewController test] + 40 at ViewController.m:30
   29  	    int b = 1;
   30  	    int c = a+b;
   31  	    NSLog(@"%d",c);
    0x10aab7968 <+40>: addl   -0x18(%rbp), %ecx
BreakPointTest`-[ViewController test] + 43 at ViewController.m:30
   29  	    int b = 1;
   30  	    int c = a+b;
   31  	    NSLog(@"%d",c);
    0x10aab796b <+43>: movl   %ecx, -0x1c(%rbp)
BreakPointTest`-[ViewController test] + 46 at ViewController.m:31
   30  	    int c = a+b;
   31  	    NSLog(@"%d",c);
   32  	}
    0x10aab796e <+46>: movl   -0x1c(%rbp), %esi
BreakPointTest`-[ViewController test] + 49 at ViewController.m:31
   30  	    int c = a+b;
   31  	    NSLog(@"%d",c);
   32  	}
    0x10aab7971 <+49>: movq   %rax, %rdi
    0x10aab7974 <+52>: movb   $0x0, %al
    0x10aab7976 <+54>: callq  0x10aab7c80               ; symbol stub for: NSLog
BreakPointTest`-[ViewController test] + 59 at ViewController.m:32
   31  	    NSLog(@"%d",c);
   32  	}
   33  	@end
    0x10aab797b <+59>: addq   $0x20, %rsp
    0x10aab797f <+63>: popq   %rbp
    0x10aab7980 <+64>: retq

      使用disassemble -p進行當前行的彙編代碼輸出:

(lldb) disassemble -p
BreakPointTest`-[ViewController test]:
->  0x10aab7965 <+37>: movl   -0x14(%rbp), %ecx
    0x10aab7968 <+40>: addl   -0x18(%rbp), %ecx
    0x10aab796b <+43>: movl   %ecx, -0x1c(%rbp)
    0x10aab796e <+46>: movl   -0x1c(%rbp), %esi

5.其餘LLDB經常使用指令

        bt指令用於打印當前線程全部堆棧塊信息:

(lldb) bt
* thread #1: tid = 0x19f11, 0x000000010aab7965 BreakPointTest`-[ViewController test](self=0x00007fee9c11e330, _cmd="test") + 37 at ViewController.m:30, queue = 'com.apple.main-thread', stop reason = breakpoint 2.1
  * frame #0: 0x000000010aab7965 BreakPointTest`-[ViewController test](self=0x00007fee9c11e330, _cmd="test") + 37 at ViewController.m:30
    frame #1: 0x000000010aab792b BreakPointTest`-[ViewController viewDidLoad](self=0x00007fee9c11e330, _cmd="viewDidLoad") + 91 at ViewController.m:22
    frame #2: 0x000000010ba95984 UIKit`-[UIViewController loadViewIfRequired] + 1198
    frame #3: 0x000000010ba95cd3 UIKit`-[UIViewController view] + 27
    frame #4: 0x000000010b96bfb4 UIKit`-[UIWindow addRootViewControllerViewIfPossible] + 61
    frame #5: 0x000000010b96c69d UIKit`-[UIWindow _setHidden:forced:] + 282
    frame #6: 0x000000010b97e180 UIKit`-[UIWindow makeKeyAndVisible] + 42
    frame #7: 0x000000010b8f2ed9 UIKit`-[UIApplication _callInitializationDelegatesForMainScene:transitionContext:] + 4131
    frame #8: 0x000000010b8f9568 UIKit`-[UIApplication _runWithMainScene:transitionContext:completion:] + 1769
    frame #9: 0x000000010b8f6714 UIKit`-[UIApplication workspaceDidEndTransaction:] + 188
    frame #10: 0x000000010e3638c8 FrontBoardServices`__FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__ + 24
    frame #11: 0x000000010e363741 FrontBoardServices`-[FBSSerialQueue _performNext] + 178
    frame #12: 0x000000010e363aca FrontBoardServices`-[FBSSerialQueue _performNextFromRunLoopSource] + 45
    frame #13: 0x000000010b46a301 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
    frame #14: 0x000000010b46022c CoreFoundation`__CFRunLoopDoSources0 + 556
    frame #15: 0x000000010b45f6e3 CoreFoundation`__CFRunLoopRun + 867
    frame #16: 0x000000010b45f0f8 CoreFoundation`CFRunLoopRunSpecific + 488
    frame #17: 0x000000010b8f5f21 UIKit`-[UIApplication _run] + 402
    frame #18: 0x000000010b8faf09 UIKit`UIApplicationMain + 171
    frame #19: 0x000000010aab7c5f BreakPointTest`main(argc=1, argv=0x00007fff55148668) + 111 at main.m:14
    frame #20: 0x000000010dd1e92d libdyld.dylib`start + 1
    frame #21: 0x000000010dd1e92d libdyld.dylib`start + 1

 

  c指令繼續運行線程process continue效果同樣。

        call指令運行一個表達式, expression 效果同樣。

        detach指令結束當前調試的線程。

        di指令反彙編當前函數disassemble相同。

        exit指令退出lldb調試器。

        finish指令完成當前堆棧塊的調試,程序會繼續運行。

        n指令進行單步調試,next做用同樣。

        p指令expression做用同樣。

        print指令用於變量的打印。

        r指令從新運行應用程序。

        quit指令結束調試。

        bugreport指令用於建立堆棧信息報告。

        command history指令用於打印LLDB調試命令記錄。

        help指令用於查詢LLDB相關調試指令的用法。

        apropo指令用於查詢某些包含某些關鍵字的指令。

        version指令用於查詢LLDB調試器的版本,以下:

(lldb) version
lldb-350.0.21.3

        image list命令用於打印工程中全部用到的庫文件。

       image相關指令還有一個十分有用的命令,image lookup --address能夠查詢某個內存地址的內容,以下:

(lldb) image lookup --address 0x000000010373e885
      Address: CoreFoundation[0x00000000000f4885] (CoreFoundation.__TEXT.__text + 996309)
      Summary: CoreFoundation`-[__NSArray0 objectAtIndex:] + 101

        image lookup --type用於查詢某種類型中包含的屬性,以下:

(lldb) image lookup --type UILabel
Best match found in /Users/vip/Library/Developer/Xcode/DerivedData/BreakPointTest-cearqrjqbntqcnfgiqzpxhyadewi/Build/Products/Debug-iphonesimulator/BreakPointTest.app/BreakPointTest:
id = {0x000082c1}, name = "UILabel", byte-size = 8, decl = UILabel.h:18, compiler_type = "@interface UILabel : UIView
@property ( getter = text,setter = setText:,readwrite,copy,nonatomic ) NSString * text;
@property ( getter = font,setter = setFont:,readwrite,nonatomic ) UIFont * font;
@property ( getter = textColor,setter = setTextColor:,readwrite,nonatomic ) UIColor * textColor;
@property ( getter = shadowColor,setter = setShadowColor:,readwrite,nonatomic ) UIColor * shadowColor;
@property ( getter = shadowOffset,setter = setShadowOffset:,assign,readwrite,nonatomic ) CGSize shadowOffset;
@property ( getter = textAlignment,setter = setTextAlignment:,assign,readwrite,nonatomic ) NSTextAlignment textAlignment;
@property ( getter = lineBreakMode,setter = setLineBreakMode:,assign,readwrite,nonatomic ) NSLineBreakMode lineBreakMode;
@property ( getter = attributedText,setter = setAttributedText:,readwrite,copy,nonatomic ) NSAttributedString * attributedText;
@property ( getter = highlightedTextColor,setter = setHighlightedTextColor:,readwrite,nonatomic ) UIColor * highlightedTextColor;
@property ( getter = isHighlighted,setter = setHighlighted:,assign,readwrite,nonatomic ) BOOL highlighted;
@property ( getter = isUserInteractionEnabled,setter = setUserInteractionEnabled:,assign,readwrite,nonatomic ) BOOL userInteractionEnabled;
@property ( getter = isEnabled,setter = setEnabled:,assign,readwrite,nonatomic ) BOOL enabled;
@property ( getter = numberOfLines,setter = setNumberOfLines:,assign,readwrite,nonatomic ) NSInteger numberOfLines;
@property ( getter = adjustsFontSizeToFitWidth,setter = setAdjustsFontSizeToFitWidth:,assign,readwrite,nonatomic ) BOOL adjustsFontSizeToFitWidth;
@property ( getter = baselineAdjustment,setter = setBaselineAdjustment:,assign,readwrite,nonatomic ) UIBaselineAdjustment baselineAdjustment;
@property ( getter = minimumScaleFactor,setter = setMinimumScaleFactor:,assign,readwrite,nonatomic ) CGFloat minimumScaleFactor;
@property ( getter = allowsDefaultTighteningForTruncation,setter = setAllowsDefaultTighteningForTruncation:,assign,readwrite,nonatomic ) BOOL allowsDefaultTighteningForTruncation;
@property ( getter = preferredMaxLayoutWidth,setter = setPreferredMaxLayoutWidth:,assign,readwrite,nonatomic ) CGFloat preferredMaxLayoutWidth;
@property ( getter = minimumFontSize,setter = setMinimumFontSize:,assign,readwrite,nonatomic ) CGFloat minimumFontSize;
@property ( getter = adjustsLetterSpacingToFitWidth,setter = setAdjustsLetterSpacingToFitWidth:,assign,readwrite,nonatomic ) BOOL adjustsLetterSpacingToFitWidth;
@end"

       x指令能夠讀取某段內存的二進制數據:

(lldb) x 0x000000010373e885
0x10373e885: 66 66 2e 0f 1f 84 00 00 00 00 00 55 48 89 e5 48  ff.........UH..H
0x10373e895: 8d 3d 6d f2 28 00 e8 c0 d9 f0 ff 48 89 05 c1 58  .=m.(......H...X

 

        LLDB的用法和技巧還有不少,它能夠大大提升咱們調試代碼的效率,有疏漏和錯誤之處,還望與志同道合的朋友共同窗習進步。

專一技術,熱愛生活,交流技術,也作朋友。

——琿少 QQ羣:203317592

相關文章
相關標籤/搜索