lldb的若干技巧及拾遺

機緣

之前有一陣以爲chisel真的挺好用的,後來翻看了歷年的WWDC關於lldb的video 仍是發現一些tipspython

Tip

lldb 統一格式

  • <noun> <verb> [options] [argument [argument ...]]git

lldb 命令行都遵循上述格式,例如:github

target create /bin/ls
breakpoint set —-name malloc
process attach --pid 1234
breakpoint set --file hello.c --line 100
breakpoint modify —condition 「self = $myModel"

lldb簡寫

help -> h
expression -O -- -> po
expression -- -> p
thread until 11 -> th u 11
breakpoint modify —condition "self = $myModel" -> br m -c 「self == $myModel"objective-c

lldb command alias

lldb 啓動都會加載 ~/.lldbinit,故而咱們能夠經過修改它來實現本身的加強shell

例如command alias,常見的例子,譬如耳熟能詳的Reveal能經過下列命令啓動express

command alias reveal_load_sim expr (void*)dlopen("/Applications/Reveal.app/Contents/SharedSupport/iOS-Libraries/libReveal.dylib", 0x2);

我本身擴展了這個別名pwv:segmentfault

command alias pwv expr (void)NSLog((NSString*)[[[UIApplication sharedApplication] keyWindow] recursiveDescription])

該命令能夠打印keyWindow上的view的層級結構。app

command regex

一樣放在~/.lldbinit,跟alias相似,不過能夠帶參數,使用正則。dom

command regex pv 's/(.+)/expr (void)NSLog((NSString*)[(UIView*)%1 recursiveDescription])/'

command regex postNoti 's/(.+)/expr (void)[[NSNotificationCenter defaultCenter] postNotificationName:%1 object:nil]/'

命令pv %1用來打印%1上的全部view的層級結構。
命令postNoti %1 用來post 一個notication如:ide

(lldb) postNoti @"MyNotification"

根據平常開發的須要,aliasregex均可以用來當作打開/關閉某些擴展功能,如第三方的調試工具:

打開/關閉FLEX
command alias flex expr [[FLEXManager sharedManager] toggleExplorer]

regex我用得也比較簡單,基本跟alias差很少。相信還會有更geek的用法。

command script

chisel就是用下列命令初始化的:

command script import /path/to/fblldb.py
  • simple example

myCommands.py

def caflushCommand(debugger, command, result, internal_dict):
debugger.HandleCommand("e (void)[CATransaction flush]")
command script import ~/myCommands.py

lldb關於python的接口我看得也不細,具體參見wwdc和lldb。chisel的github上也有講。

流程控制

下列命令其意不言自明,平常其實不必定能用到,但thread return在debug時仍是至關有用的,調試時發現某些bug,當重現步驟又太麻煩,不想修改代碼後從新編譯,能夠在某些critical method中進行fake return。

process continue continue c
thread step-over next n
thread step-in step s
thread step-out finish

thread return

thread return
thread return NO
thread return @"hi"

Examining Data

frame variable

(lldb) fr v self

(MyProject.ViewController) self = 0x00007fd63c221fa0 {
UIKit.UIViewController = {

UIResponder = {
  NSObject = {
    isa = YourProject.ViewController
  }
  _hasAlternateNextResponder = false
  _hasInputAssistantItem = false
}
_overrideTransitioningDelegate = nil
如下省略

其餘拾遺

  • 寄存器相關

(lldb) register read
General Purpose Registers:
       rax = 0x0000000010004005
       rbx = 0x00000000ffffffff
       rcx = 0x00007fff5559b718
       rdx = 0x0000000000000000
       rdi = 0x00007fff5559b880
       rsi = 0x0000000007000806
       rbp = 0x00007fff5559b760
       rsp = 0x00007fff5559b718
        r8 = 0x0000000000001403
        r9 = 0x00000000ffffffff
       r10 = 0x0000000000000c00
       r11 = 0x0000000000000206
       r12 = 0x0000000000000c00
       r13 = 0x0000000000000000
       r14 = 0x00007fff5559b880
       r15 = 0x0000000000001403
       rip = 0x000000010e151386  libsystem_kernel.dylib`mach_msg_trap + 10
    rflags = 0x0000000000000206
        cs = 0x000000000000002b
        fs = 0x0000000000000000
        gs = 0x0000000000000000
  • platform shell
    在lldb中執行shell命令,如

(lldb)platform shell ls
  • objective-c set exception 斷點

(lldb) br s -E objc
  • 查看類型

(lldb) type lookup ErrorType
protocol ErrorType {
  var _domain: Swift.String { get }
  var _code: Swift.Int { get }
}
extension ErrorType {
  var _domain: Swift.String {
    get {}
  }
}
  • 其餘
    wwdc上有說修好了lldb的一些known issue,好比

(lldb) p NSLog(@「%d」, i)
error: 'NSLog' has unknown return type;
  cast the call to its declared return type
error: 1 errors parsing expression
(lldb) p [NSApplication sharedApplication].undoManager error: property ‘undoManager’ not found on object of type ‘id’
error: 1 errors parsing expression

這些問題都修好了。

總結

其餘的之後再補充。
有些東西其實對於大多數開發者用處不大,你們隨便看看。

原做寫於segmentfault 連接

相關文章
相關標籤/搜索