Xcode-lldb的使用

meryin發表於2018-05-08

一 程式碼斷點

  • 設定斷點
    2.png
    設定多個oc方法的斷點:breakpoint set -n "-[ViewController save:]" -n "-[ViewController pauseGame:]"
  • 檢視斷點 breakpoint list
  • 繼續程式 c
  • 禁用斷點 breakpoint disable 2.1禁用第二組的第一個斷點
  • 啟用斷點 breakpoint enable 2.1
  • 刪除斷點:只能刪除某組斷點breakpoint delete 3,如果breakpoint delete 3.1起到的是禁用3.1的作用
  • 檢視lldb指令:help
help breakpoint
     Commands for operating on breakpoints (see 'help b' for shorthand.)

Syntax: breakpoint

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>'.
複製程式碼
  • 設定所有的save:方法的斷點 breakpoint set --selector save:
  • 設定某個檔案中的save:方法的斷點:breakpoint set --file ViewController.m --selector save:
  • 全域性遍歷專案中所有方法名中包含某欄位的斷點:breakpoint set -r Game:

二 執行程式碼進行除錯

  • expression 簡寫p
(lldb) expression self.view.subviews
(NSArray *) $0 = 0x0000000159e38920
(lldb) p self.view.backgroundColor = [UIColor yellowColor]
(UIColor *) $1 = 0x0000000159e837f0
(lldb) c
Process 80637 resuming
2018-05-07 16:20:42.198488+0800 001--LLDB[80637:7308534] XPC connection interrupted
2018-05-07 16:21:00.038626+0800 001--LLDB[80637:7308097] Status bar could not find cached time string image. Rendering in-process.
複製程式碼

列印物件:po self.view.subviews

  • 舉個例子?:

在陣列中加入新的Person物件

(lldb) p [self.models addObject:[Person new]];
(lldb) p (Person *)self.models.lastObject
(Person *) $3 = 0x0000000101508080
(lldb) p $3.name = @"meryin"
(NSString *) $4 = 0xa006e697972656d6
(lldb) p $3.age = 20
(int) $5 = 20
(lldb) po $3.name
meryin
複製程式碼

設定變數然後再新增:

(lldb) p Person *p4 = [Person new]; //按住control和Enter鍵,繼續程式碼
p4.name = @"tom";p4.age = 25;
[self.models addObject:p4];//最後回車
複製程式碼

三 記憶體斷點

  • 給某物件的某屬性下斷點: (lldb) watchpoint set variable p1->_name 或者利用記憶體地址下斷點:
(lldb) frame variable
(ViewController *) self = 0x0000000105ec23b0
(SEL) _cmd = "viewDidLoad"
(Person *) p1 = 0x0000000105ea8190
(Person *) p2 = 0x0000000000000010
(Person *) p3 = 0x000000016f3e5528
(lldb) p &p1->_name
(NSString **) $2 = 0x0000000105ea81a0
(lldb) watchpoint set expression 0x0000000105ea81a0
Watchpoint created: Watchpoint 2: addr = 0x105ea81a0 size = 8 state = enabled type = w
    new value: 4305584416
(lldb) watchpoint list
Number of supported hardware watchpoints: 4
Current watchpoints:
Watchpoint 2: addr = 0x105ea81a0 size = 8 state = enabled type = w
    new value: 4305584416
(lldb) 
複製程式碼

四 斷點後執行指令

(lldb) break command add 1
Enter your debugger command(s).  Type 'DONE' to end.
> p self //回車
> p self.models //回車
> DONE //回車
複製程式碼

在1組處打了斷點,斷點執行到1後會執行p self等指令 用breakpoint command list檢視斷點 用法和breakpoint一樣

五 檢視堆疊資訊

  • 函式呼叫棧:bt
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
  * frame #0: 0x000000010092e388 001--LLDB`-[ViewController touchesBegan:withEvent:](self=0x0000000100e69740, _cmd="touchesBegan:withEvent:", touches=0x0000000100fa54d0, event=0x0000000100f644d0) at ViewController.m:85
    frame #1: 0x000000018ea61870 UIKit`forwardTouchMethod + 340
    frame #2: 0x000000018e9077c8 UIKit`-[UIResponder touchesBegan:withEvent:] + 60
    frame #3: 0x000000018e901830 UIKit`-[UIWindow _sendTouchesForEvent:] + 1892
    frame #4: 0x000000018e8f68f8 UIKit`-[UIWindow sendEvent:] + 3160
    frame #5: 0x000000018e8f5238 UIKit`-[UIApplication sendEvent:] + 340
    frame #6: 0x000000018f0d6c0c UIKit`__dispatchPreprocessedEventFromEventQueue + 2340
    frame #7: 0x000000018f0d91b8 UIKit`__handleEventQueueInternal + 4744
    frame #8: 0x000000018f0d2258 UIKit`__handleHIDEventFetcherDrain + 152
    frame #9: 0x0000000184af7404 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 24
    frame #10: 0x0000000184af6c2c CoreFoundation`__CFRunLoopDoSources0 + 276
    frame #11: 0x0000000184af479c CoreFoundation`__CFRunLoopRun + 1204
    frame #12: 0x0000000184a14da8 CoreFoundation`CFRunLoopRunSpecific + 552
    frame #13: 0x00000001869f7020 GraphicsServices`GSEventRunModal + 100
    frame #14: 0x000000018e9f578c UIKit`UIApplicationMain + 236
    frame #15: 0x000000010092e54c 001--LLDB`main(argc=1, argv=0x000000016f4d79d8) at main.m:14
    frame #16: 0x00000001844a5fc0 libdyld.dylib`start + 4
複製程式碼
  • 檢視某一個函式: frame select 1
  • 檢視上一個函式:(lldb) up
  • 檢視下一個函式:(lldb) down
  • 檢視引數:
(lldb) frame variable
(ViewController *) self = 0x0000000100e69740
(SEL) _cmd = "touchesBegan:withEvent:"
(NSSet *) touches = 0x0000000100fa54d0
(UIEvent *) event = 0x0000000100f644d0
(NSString *) str = 0x0000000100e96820
(Person *) p1 = 0x0000000100faa7b0
(lldb) p str = @"xxx";
(lldb) po str
xxx
複製程式碼
  • 回滾上一個函式並不再執行:thread return

六 stop-hook

在每次斷住程式的時候去執行一些命令,只對breadpoint,watchpoint生效

(lldb) target stop-hook add -o "frame variable"
Stop hook #1 added.
(lldb) target stop-hook list
Hook: 1
  State: enabled
  Commands: 
    frame variable
複製程式碼

當某個斷點觸發後,會執行"frame variable"指令 target stop-hook用法和breakpoint 一樣,list檢視,delete刪除 刪除某組還可以用(lldb) undisplay 1 還可以用配置檔案,不用每次執行Xcode都要寫指令: 找到.lldbinit或者touch .lldbinit在此檔案中配置自己的指令。

4.png
vim .lldbinit然後target stop-hook add -o "frame variable"儲存退出,用cat .lldbinit可以看到target stop-hook add -o "frame variable"

七 image lookup檢視庫,類和崩潰等資訊

(lldb) help image lookup
     Look up information within executable and dependent shared library images.

Syntax: 

Command Options Usage:
  target modules lookup [-Av] -a <address-expression> [-o <offset>] [<filename> [<filename> [...]]]
  target modules lookup [-Arv] -s <symbol> [<filename> [<filename> [...]]]
  target modules lookup [-Aiv] -f <filename> [-l <linenum>] [<filename> [<filename> [...]]]
  target modules lookup [-Airv] -F <function-name> [<filename> [<filename> [...]]]
  target modules lookup [-Airv] -n <function-or-symbol> [<filename> [<filename> [...]]]
  target modules lookup [-Av] -t <name> [<filename> [<filename> [...]]]

       -A ( --all )
            Print all matches, not just the best match, if a best match is
            available.

       -F <function-name> ( --function <function-name> )
            Lookup a function by name in the debug symbols in one or more
            target modules.

       -a <address-expression> ( --address <address-expression> )
            Lookup an address in one or more target modules.

       -f <filename> ( --file <filename> )
            Lookup a file by fullpath or basename in one or more target
            modules.

       -i ( --no-inlines )
            Ignore inline entries (must be used in conjunction with --file or
            --function).

       -l <linenum> ( --line <linenum> )
            Lookup a line number in a file (must be used in conjunction with
            --file).

       -n <function-or-symbol> ( --name <function-or-symbol> )
            Lookup a function or symbol by name in one or more target modules.

       -o <offset> ( --offset <offset> )
            When looking up an address subtract <offset> from any addresses
            before doing the lookup.

       -r ( --regex )
            The <name> argument for name lookups are regular expressions.

       -s <symbol> ( --symbol <symbol> )
            Lookup a symbol by name in the symbol tables in one or more target
            modules.

       -t <name> ( --type <name> )
            Lookup a type by name in the debug symbols in one or more target
            modules.

       -v ( --verbose )
            Enable verbose lookup information.
     
     This command takes options and free-form arguments.  If your arguments
     resemble option specifiers (i.e., they start with a - or --), you must use
     ' -- ' between the end of the command options and the beginning of the
     arguments.

'image' is an abbreviation for 'target modules'
複製程式碼
  • 檢視崩潰資訊 比如陣列越界的崩潰資訊:
*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndexedSubscript:]: index 4 beyond bounds [0 .. 2]'
*** First throw call stack:
(0x184b4ed8c 0x183d085ec 0x184ae7750 0x184ad48cc 0x1007ae328 0x18ea61870 0x18e9077c8 0x18e901830 0x18e8f68f8 0x18e8f5238 0x18f0d6c0c 0x18f0d91b8 0x18f0d2258 0x184af7404 0x184af6c2c 0x184af479c 0x184a14da8 0x1869f7020 0x18e9f578c 0x1007ae52c 0x1844a5fc0)
libc++abi.dylib: terminating with uncaught exception of type NSException
複製程式碼

用image lookup -a檢視資訊,找到崩潰的方法-[ViewController touchesBegan:withEvent:]

(lldb) image lookup -a 0x184b4ed8c
      Address: CoreFoundation[0x0000000180ef6d8c] (CoreFoundation.__TEXT.__text + 1313804)
      Summary: CoreFoundation`__exceptionPreprocess + 228
(lldb) image lookup -a 0x1007ae328 
      Address: 001--LLDB[0x0000000100006328] (001--LLDB.__TEXT.__text + 1796)
      Summary: 001--LLDB`-[ViewController touchesBegan:withEvent:] + 160 at ViewController.m:86
(lldb) image lookup -a 0x18ea61870
      Address: UIKit[0x000000018ae09870] (UIKit.__TEXT.__text + 3699592)
      Summary: UIKit`forwardTouchMethod + 340
複製程式碼
  • 檢視類資訊 image lookup -t Person
  • image list檢視當前用到的庫

八 其他指令

  • 單步執行(子函式當成整體):n
  • 單步執行(進入子函式):s
  • 彙編的單步(子函式當成整體):ni
  • 彙編的單步(進入子函式):si
    3.png