Advanced.Apple.Debugging.&.Reverse.Engineering.v2.0 學(xué)習(xí)筆記
1. 入門
1.1 禁用Rootless 與開啟調(diào)試功能
為了提高系統(tǒng)的安全性,Mac OS X 10.11開始引入了Rootless,在Rootless開啟的情況下,LLDB無法調(diào)試到其它進(jìn)程(模擬器內(nèi)的進(jìn)程除外).如果想調(diào)試其它進(jìn)程,需要關(guān)閉Rootless,如下:
- 重啟系統(tǒng)
- 開機(jī)后按下
Command + R
直到進(jìn)入恢復(fù)模式 - 從頂部菜單中找到
Utilities
菜單并選擇Terminal
- 輸入以下命令禁用Rootless
csrutil disable
reboot
1.2 使用LLDB基本流程-使用LLDB 調(diào)試Xcode
實(shí)現(xiàn)如下功能
- 使用LLDB調(diào)試Xcode
- 將Xcode的輸出重定向到終端
1.2.1 創(chuàng)建重定向終端(tty
)
使用tty
命令創(chuàng)建重定向終端,此時(shí)生成的終端名為ttys002
~ tty
/dev/ttys001
1.2.2 使用LLDB啟動(dòng)Xcode
- 使用
lldb
命令進(jìn)入LLDB - 設(shè)置可執(zhí)行目標(biāo)文件路徑(
file
命令):
(lldb) file /Applications/Xcode.app/Contents/MacOS/Xcode
Current executable set to '/Applications/Xcode.app/Contents/MacOS/Xcode' (x86_64).
其中/Applications/Xcode.app/Contents/MacOS/Xcode
為Xcode的可執(zhí)行路徑,在Xcode打開的情況下可以通過以下命令獲取
~ ps -ef `pgrep -x Xcode`
UID PID PPID C STIME TTY TIME CMD
501 29508 1 0 8:29下午 ?? 0:14.03 /Applications/Xcode.app/Contents/MacOS/Xcode
- 啟動(dòng)并重定向到終端(之前創(chuàng)建的重定向終端:ttys001)
(lldb) process launch -e /dev/ttys001 --
Process 92898 launched: '/Applications/Xcode.app/Contents/MacOS/Xcode' (x86_64)
-
Ctrl + C
暫停調(diào)試器 - 設(shè)置斷點(diǎn)(
b
):
(lldb) b -[NSView hitTest:]
Breakpoint 1: where = AppKit`-[NSView hitTest:], address = 0x00007fff31e25f9b
- 繼續(xù)調(diào)試(
continue
)
(lldb) continue
Process 34209 resuming
- 觸發(fā)斷點(diǎn): 點(diǎn)擊Xcode任意區(qū)域
Process 92898 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
frame #0: 0x00007fff31e25f9b AppKit`-[NSView hitTest:]
AppKit`-[NSView hitTest:]:
-> 0x7fff31e25f9b <+0>: pushq %rbp
0x7fff31e25f9c <+1>: movq %rsp, %rbp
0x7fff31e25f9f <+4>: pushq %r15
0x7fff31e25fa1 <+6>: pushq %r14
Target 0: (Xcode) stopped.
- 查看那個(gè)視圖被點(diǎn)擊(
po
命令):
(lldb) po $rdi
<NSThemeFrame: 0x1651174c0>
(lldb) po [$rdi superclass]
NSTitledFrame
(lldb) po [[$rdi superclass] superclass]
NSFrameView
(lldb) po [[[$rdi superclass] superclass] superclass]
NSView
$rdi 寄存器包含調(diào)用hitTest:方法的子類NSView的實(shí)例
1.3 常用快捷鍵
-
Ctrl + C
:暫停調(diào)試器 -
Ctrl + D
:結(jié)束調(diào)試 -
Command + K
: 清空debug區(qū)域輸出
2. LLDB 幫助與查詢
2.1 LLDB命令格式
<noun> <verb> [-options [option-value]] [argument [argument...]]
即:<關(guān)鍵字> <動(dòng)作> [-可選項(xiàng) [可選項(xiàng)的值]] [參數(shù)1 [參數(shù)2···]]
- 所有命令使用同一的格式
- 參數(shù),可選項(xiàng)和選項(xiàng)值都用空格分隔
- 使用雙引號(hào)保護(hù)參數(shù)中的空格內(nèi)容
-
\
和"
使用\
進(jìn)行轉(zhuǎn)義,如\"
表示"
,\\
表示\
- 如果參數(shù)以
-
開始,需要在可選項(xiàng)和參數(shù)之間使用--
加以分隔 - 可選項(xiàng)的順序可以不固定
(lldb) process launch --stop-at-entry -- -program_arg_1 value -program_arg_2 value
關(guān)鍵字:process
動(dòng)作:launch
可選項(xiàng):-stop-at-entry
參數(shù):-program_arg_1、-program_arg_2 value
作用:啟動(dòng)程序并傳入 `-program_arg value` 作為參數(shù)
2.2 help
命令獲取幫助
2.2.1 help
命令概覽:help
(lldb) help
Debugger commands:
apropos -- List debugger commands related to a word or subject.
breakpoint -- Commands for operating on breakpoints (see 'help b' for shorthand.)
command -- Commands for managing custom LLDB commands.
disassemble -- Disassemble specified instructions in the current target. Defaults to the current function for the current thread and stack frame.
expression -- Evaluate an expression on the current thread. Displays any returned value with LLDB's default formatting.
frame -- Commands for selecting and examing the current thread's stack frames.
gdb-remote -- Connect to a process via remote GDB server. If no host is specifed, localhost is assumed.
gui -- Switch into the curses based GUI mode.
help -- Show a list of all debugger commands, or give details about a specific command.
kdp-remote -- Connect to a process via remote KDP server. If no UDP port is specified, port 41139 is assumed.
language -- Commands specific to a source language.
log -- Commands controlling LLDB internal logging.
memory -- Commands for operating on memory in the current target process.
platform -- Commands to manage and create platforms.
plugin -- Commands for managing LLDB plugins.
process -- Commands for interacting with processes on the current platform.
quit -- Quit the LLDB debugger.
register -- Commands to access registers for the current thread and stack frame.
2.2.2 help
命令格式:help help
通過help help
客戶獲取help的命令格式
(lldb) help help
Show a list of all debugger commands, or give details about a specific command.
Syntax: help [<cmd-name>]
Command Options Usage:
help [-ahu] [<cmd-name> [<cmd-name> [...]]]
-a ( --hide-aliases )
Hide aliases in the command list.
-h ( --show-hidden-commands )
Include commands prefixed with an underscore.
-u ( --hide-user-commands )
Hide user-defined commands from the list.
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.
2.2.3查詢斷點(diǎn)的幫助文檔:help breakpoint
(lldb) 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>'.
2.3 查詢命令:apropos
在不知道具體命令但知道相應(yīng)關(guān)鍵字的時(shí)候,可以用apropos
命令進(jìn)行查詢,語法如下
apropos <search-word>
比如查詢跟Objective-C
相關(guān)的命令
(lldb) apropos Objective-C
The following commands may relate to 'Objective-C':
objc -- Commands for operating on the Objective-C language runtime.
class-table -- Commands for operating on the Objective-C class table.
dump -- Dump information on Objective-C classes known to the current process.
tagged-pointer -- Commands for operating on Objective-C tagged pointers.
查詢引用計(jì)數(shù)相關(guān)的命令
(lldb) apropos "reference count"
The following commands may relate to 'reference count':
refcount -- Inspect the reference count data for a Swift object
3. 使用LLDB附加到進(jìn)程
3.1 附加到現(xiàn)有進(jìn)程
- 通過進(jìn)程名,相當(dāng)于:
process attach --name
~ lldb -n Xcode
(lldb) process attach --name "Xcode"
- 通過進(jìn)程ID,相當(dāng)于:
process attach --pid
~ pgrep -x Xcode
2253
~ lldb -p 2253
(lldb) process attach --pid 2253
3.2 附加到即將啟動(dòng)的進(jìn)程
上面的命令只能附加到正在運(yùn)行的進(jìn)程翔试。如果Xcode沒有運(yùn)行恕洲,或者已經(jīng)附加到調(diào)試器委乌,前面的命令將失敗精置。在不知道PID的情況下夭织,如何捕捉即將啟動(dòng)的進(jìn)程呢?
3.2.1 通過添加 -w
參數(shù)附加到即將啟動(dòng)的進(jìn)程: lldb -n <進(jìn)程名> -w
lldb -n <進(jìn)程名> -w
相當(dāng)于: (lldb) process attach --name <進(jìn)程名> --waitfor
比如我們想附加到即將啟動(dòng)的Finder
進(jìn)程,可如下實(shí)現(xiàn)
- 在終端1 輸入如下命令等待附加到即將啟動(dòng)的
Finder
進(jìn)程
~ lldb -n Finder -w
(lldb) process attach --name "Finder" --waitfor
- 在終端2 輸入如下命令,該命令將關(guān)閉所有
Finder
~ pkill Finder
- 系統(tǒng)將自動(dòng)啟動(dòng)
Finder
,等系統(tǒng)啟動(dòng)Finder
后,終端1 LLDB將附加到Finder
進(jìn)程,如下輸出:
Process 4476 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP
frame #0: 0x00007fff6ebabdfa libsystem_kernel.dylib`mach_msg_trap + 10
libsystem_kernel.dylib`mach_msg_trap:
-> 0x7fff6ebabdfa <+10>: retq
0x7fff6ebabdfb <+11>: nop
libsystem_kernel.dylib`mach_msg_overwrite_trap:
0x7fff6ebabdfc <+0>: movq %rcx, %r10
0x7fff6ebabdff <+3>: movl $0x1000020, %eax ; imm = 0x1000020
Target 0: (Finder) stopped.
Executable module set to "/System/Library/CoreServices/Finder.app/Contents/MacOS/Finder".
Architecture set to: x86_64h-apple-macosx-.
3.2.2 通過指定可執(zhí)行文件路徑附加到即將啟動(dòng)的進(jìn)程: lldb -f <進(jìn)程路徑>
- 通過
lldb -f <進(jìn)程路徑>
命令指定可執(zhí)行文件
~ lldb -f /System/Library/CoreServices/Finder.app/Contents/MacOS/Finder
- 運(yùn)行
process launch
命令啟動(dòng)進(jìn)程
注意:直接使用
process launch
命令啟動(dòng)進(jìn)程,被調(diào)試進(jìn)程的stderr輸出會(huì)自動(dòng)發(fā)送到當(dāng)前終端窗口.我們可以通過-e
參數(shù)將輸出重定向到其它終端
process launch -e /dev/ttys001 --
3.3 process launch 詳解
以調(diào)試 ls
命令為例子
3.3.1 修改被調(diào)試進(jìn)程工作路徑: process launch -w
默認(rèn)情況下,被調(diào)試進(jìn)程會(huì)工作在當(dāng)前目錄,在當(dāng)前目錄執(zhí)行ls
,輸出的是當(dāng)前目錄下的文件列表.
~ lldb -f /bin/ls
(lldb) target create "/bin/ls"
Current executable set to '/bin/ls' (x86_64).
(lldb) process launch
Process 6375 launched: '/bin/ls' (x86_64)
Applications Music
Applications (Parallels) Parallels
Desktop Pictures
Documents Public
Downloads markdown.md
Library sslkeylog.log
Movies
Process 6375 exited with status = 0 (0x00000000)
如果想改變被調(diào)試進(jìn)程的工作目錄路徑,我們可以通過添加-w
參數(shù)實(shí)現(xiàn),如:
~ lldb -f /bin/ls
(lldb) target create "/bin/ls"
Current executable set to '/bin/ls' (x86_64).
(lldb) process launch -w /Users/Shared
Process 7130 launched: '/bin/ls' (x86_64)
Parallels SC Info
Previously Relocated Items adi
Process 7130 exited with status = 0 (0x00000000)
輸出/Users/Shared,跟上面列出的文件列表一樣
? Shared pwd
/Users/Shared
? Shared ls
Parallels Previously Relocated Items SC Info adi
3.3.2 傳遞啟動(dòng)參數(shù)給目標(biāo)進(jìn)程
我們也可以將參數(shù)傳遞給目標(biāo)進(jìn)程,注意中間的--
,用以區(qū)分選項(xiàng)和參數(shù)
? ~ pwd
/Users/sammylan
? ~ ls /Users/Shared
Parallels Previously Relocated Items SC Info adi
? ~ lldb -f /bin/ls
(lldb) target create "/bin/ls"
Current executable set to '/bin/ls' (x86_64).
(lldb) process launch -- /Users/Shared
Process 8074 launched: '/bin/ls' (x86_64)
Parallels SC Info
Previously Relocated Items adi
Process 8074 exited with status = 0 (0x00000000)
3.3.3 啟動(dòng)參數(shù)環(huán)境變量展開: process launch -X true
如果傳遞的參數(shù)里面有環(huán)境變量,如~
,則無法將參數(shù)正確傳遞過去,如下,ls無法展開~/Public
~ lldb -f /bin/ls
(lldb) target create "/bin/ls"
Current executable set to '/bin/ls' (x86_64).
(lldb) process launch -- ~/Public
Process 8464 launched: '/bin/ls' (x86_64)
ls: ~/Public: No such file or directory
Process 8464 exited with status = 1 (0x00000001)
這時(shí)候需要傳遞-X true
參數(shù)給process launch
(lldb) process launch -Xtrue -- ~/Public
Process 8654 launched: '/bin/ls' (x86_64)
Drop Box
Process 8654 exited with status = 0 (0x00000000)
X選項(xiàng)擴(kuò)展您提供的任何shell參數(shù)孟辑,例如波浪號(hào)计露。在LLDB中有一個(gè)快捷命令run
可實(shí)現(xiàn)類似功能,如
(lldb) run ~/Public
Process 8792 launched: '/bin/ls' (x86_64)
Drop Box
Process 8792 exited with status = 0 (0x00000000)
查看其幫助文檔可發(fā)現(xiàn),它等價(jià)于process launch -X true --
命令
(lldb) help run
Launch the executable in the debugger.
Syntax: run [<run-args>]
Command Options Usage:
run [<run-args>]
'run' is an abbreviation for 'process launch -X true --'
3.3.4 輸出重定向:process launch -o
- 重定向到文件:
(lldb) process launch -o /tmp/ls_output.txt -- /Applications
Process 9397 launched: '/bin/ls' (x86_64)
Process 9397 exited with status = 0 (0x00000000)
- 重定向到終端
(lldb) process launch -o /dev/ttys001 --
Process 9647 launched: '/bin/ls' (x86_64)
Process 9647 exited with status = 0 (0x00000000)
執(zhí)行上述命令后,將會(huì)輸出到終端ttys001,如下
3.3.5 輸入重定向:process launch -i
- 將文件內(nèi)容輸出到文件
~ echo "hello world" > /tmp/wc_input.txt
通過wc統(tǒng)計(jì)
target create /usr/bin/wc
Current executable set to '/usr/bin/wc' (x86_64).
(lldb) process launch -i /tmp/wc_input.txt
Process 10159 launched: '/usr/bin/wc' (x86_64)
1 2 12
對(duì)于需要輸入的程序,如wc
,如果沒有設(shè)置輸入重定向,程序啟動(dòng)后會(huì)掛在那里等待輸入,如下啟動(dòng),當(dāng)執(zhí)行run
后,會(huì)一直停在那里等待輸入.輸入"helloworld"并按回車,然后按Ctrl + D
,結(jié)束輸入,之后wc將結(jié)束輸入并退出,如下
(lldb) target create /usr/bin/wc
Current executable set to '/usr/bin/wc' (x86_64).
(lldb) run
Process 12287 launched: '/usr/bin/wc' (x86_64)
hello world
1 2 12
Process 12287 exited with status = 0 (0x00000000)
3.3.7 不創(chuàng)建標(biāo)準(zhǔn)輸入:process launch -n
n
選項(xiàng)告訴LLDB不要?jiǎng)?chuàng)建stdin;因此wc沒有要處理的數(shù)據(jù)添履,并立即退出屁倔。
(lldb) target create /usr/bin/wc
Current executable set to '/usr/bin/wc' (x86_64).
(lldb) process launch -n
Process 12623 launched: '/usr/bin/wc' (x86_64)
Process 12623 exited with status = 0 (0x00000000)
3.3.8 錯(cuò)誤重定向:process launch -e
將錯(cuò)誤重定向到其它終端
process launch -e /dev/ttys001 --
4. 斷點(diǎn)
4.1 image lookup: 查找符號(hào)
-
image lookup -a
: 根據(jù)地址查找符號(hào)信息 -
image lookup -n
: 根據(jù)符號(hào)名字查找符號(hào)信息 -
image lookup -r
: 啟用正則表達(dá)式查找符號(hào)
image lookup -rn "UIViewController" ;查找UIViewController相關(guān)的全部符號(hào)
image lookup -rn "-\[UIViewController" ;查找UIViewController的實(shí)例方法
image lookup -rn "\+\[UIViewController"; 查找UIViewController的類方法
image lookup -rn "-\[UIViewController\sset" ; 查找UIViewController的所有set方法
image lookup -rn "-\[UIViewController\(\w+\)" 查找UIViewController的所有分類的方法
注意,以下字符需要轉(zhuǎn)義:
[
,]
,(
,)
,(空格,也可以用
\s
代替),+
,-
image lookup 的詳細(xì)命令參數(shù)如下:
(lldb) help image lookup
Look up information within executable and dependent shared library images.
Syntax: target modules lookup <cmd-options> [<filename> [<filename> [...]]]
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.
4.2 屬性名字重整
4.2.1 Objective-C 屬性名字重整
在Objective-C中如下定義一個(gè)屬性: name
@interface TestClass : NSObject
@property (nonatomic, strong) NSString *name;
@end
會(huì)生成如下兩個(gè)setter
和getter
方法:
-[TestClass name];
-[TestClass setName:];
4.2.2 Swift 屬性名字重整
在Swift中如下定義一個(gè)屬性: name
class SwiftTestClass: NSObject {
var name: String!
}
會(huì)生成如下兩個(gè)setter
和getter
方法,其中Signals
是模塊名
Signals.SwiftTestClass.name.getter;
Signals.SwiftTestClass.name.setter;
通過如下命令查詢會(huì)發(fā)現(xiàn)還有其它一些不常用的方法,這里不做詳細(xì)討論:
image lookup -rn Signals.SwiftTestClass.name
7 matches found in /Users/sammylan/Library/Developer/Xcode/DerivedData/Signals-efbmlrmvuqjbiyfptsisstosyqdx/Build/Products/Debug-iphonesimulator/Signals.app/Signals:
Address: Signals[0x000000010000e500] (Signals.__TEXT.__text + 44608)
Summary: Signals`variable initialization expression of Signals.SwiftTestClass.name : Swift.Optional<Swift.String> at <compiler-generated> Address: Signals[0x000000010000e510] (Signals.__TEXT.__text + 44624)
Summary: Signals`key path getter for Signals.SwiftTestClass.name : Swift.Optional<Swift.String> : Signals.SwiftTestClass at <compiler-generated> Address: Signals[0x000000010000e580] (Signals.__TEXT.__text + 44736)
Summary: Signals`key path setter for Signals.SwiftTestClass.name : Swift.Optional<Swift.String> : Signals.SwiftTestClass at <compiler-generated> Address: Signals[0x000000010000e620] (Signals.__TEXT.__text + 44896)
Summary: Signals`Signals.SwiftTestClass.name.getter : Swift.Optional<Swift.String> at SwiftTestClass.swift:28 Address: Signals[0x000000010000e6c0] (Signals.__TEXT.__text + 45056)
Summary: Signals`Signals.SwiftTestClass.name.setter : Swift.Optional<Swift.String> at SwiftTestClass.swift:28 Address: Signals[0x000000010000e780] (Signals.__TEXT.__text + 45248)
Summary: Signals`Signals.SwiftTestClass.name.modify : Swift.Optional<Swift.String> at SwiftTestClass.swift:28 Address: Signals[0x000000010000e7d0] (Signals.__TEXT.__text + 45328)
Summary: Signals`Signals.SwiftTestClass.name.modify : Swift.Optional<Swift.String> at SwiftTestClass.swift:28
4.3 創(chuàng)建斷點(diǎn)
4.3.1 創(chuàng)建斷點(diǎn):b
(_regexp-break
)
(lldb) help b
Set a breakpoint using one of several shorthand formats. Expects 'raw'
input (see 'help raw-input'.)
Syntax:
_regexp-break <filename>:<linenum>
main.c:12 // Break at line 12 of main.c
_regexp-break <linenum>
12 // Break at line 12 of current file
_regexp-break 0x<address>
0x1234000 // Break at address 0x1234000
_regexp-break <name>
main // Break in 'main' after the prologue
_regexp-break &<name>
&main // Break at first instruction in 'main'
_regexp-break <module>`<name>
libc.so`malloc // Break in 'malloc' from 'libc.so'
_regexp-break /<source-regex>/
/break here/ // Break on source lines in current file
// containing text 'break here'.
'b' is an abbreviation for '_regexp-break'
4.3.2創(chuàng)建斷點(diǎn):rb
(breakpoint set -r %1
)
使用正則表達(dá)式方式創(chuàng)建斷點(diǎn),如過使用b
創(chuàng)建前面的斷點(diǎn),需要如下方式創(chuàng)建
(lldb) b Signals.SwiftTestClass.name.setter : Swift.Optional<Swift.String>
Breakpoint 15: where = Signals`Signals.SwiftTestClass.name.setter : Swift.Optional<Swift.String> + 174 at SwiftTestClass.swift:28:7, address = 0x000000010da5376e
(lldb) b SwiftTestClass.name.setter : Swift.Optional<Swift.String>
Breakpoint 16: no locations (pending).
WARNING: Unable to resolve breakpoint to any actual locations.
如果使用rb
命令,可以簡化成如下命令
(lldb) rb SwiftTestClass.name.setter
Breakpoint 14: where = Signals`Signals.SwiftTestClass.name.setter : Swift.Optional<Swift.String> + 174 at SwiftTestClass.swift:28:7, address = 0x000000010da5376e
常用選項(xiàng):(詳細(xì)命令請參考:help rb
)
-
-s
:限定某個(gè)庫的符號(hào),如:rb . -s UIKit
UIKit的所有符號(hào)設(shè)置一個(gè)斷點(diǎn) -
-o
: 斷點(diǎn)只執(zhí)行一次,執(zhí)行后就刪除 -
-L
: 按照語言來篩選,如:rb . -L swift -s Commons
,這將在Commons模塊中的每個(gè)Swift方法上設(shè)置一個(gè)斷點(diǎn)
4.3.3 創(chuàng)建斷點(diǎn):breakpoint set
-
-p
選項(xiàng):源碼正則選項(xiàng),在符合特定源碼規(guī)則的地方停止
-
breakpoint set -A -p "if let"
: 在包含if-let的每個(gè)源代碼位置上創(chuàng)建一個(gè)斷點(diǎn) -
breakpoint set -p "if let" -s Signals -A
: 在Signals里包含if-let的每個(gè)源代碼位置上創(chuàng)建一個(gè)斷點(diǎn)
-
-c
選項(xiàng):條件斷點(diǎn):
-
breakpoint set -n "-[UIViewController viewDidLoad]" -c "*(uintptr_t*)$rsp >= 0x0000000102573000 && *(uintptr_t*)$rsp <= 0x0000000102587000"
只有從Signals
模塊調(diào)用-[UIViewController viewDidLoad]
- 獲取模塊地址:
(lldb) image dump sections Signals
4.4 管理斷點(diǎn):
-
breakpoint list
: 列出斷點(diǎn) -
breakpoint delete
: 刪除斷點(diǎn) -
breakpoint set
: 設(shè)置斷點(diǎn)
(lldb) 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>'.
5. 表達(dá)式
5.1 po
格式化輸出與修改值
-
po
輸出的是debugDescription
的內(nèi)容 -
debugDescription
默認(rèn)調(diào)用description
- 可以通過
(lldb) image lookup -rn '\ debugDescription\]'
命令查找實(shí)現(xiàn)了debugDescription
的類
(lldb) po self
debugDescription of <ViewController: 0x7f801bc05770>
(lldb) po [self description]
description of ViewController
(lldb) po [self debugDescription]
debugDescription of <ViewController: 0x7f801bc05770>
(lldb) po self.view.layer
<CALayer:0x600001c3c760; name = "VC:ViewController"; position = CGPoint (207 368); bounds = CGRect (0 0; 414 736); delegate = <UIView: 0x7fe813c09da0; frame = (0 0; 414 736); autoresize = W+H; layer = <CALayer: 0x600001c3c760>>; allowsGroupOpacity = YES; name = VC:ViewController; backgroundColor = <CGColor 0x600003f232f0> [<CGColorSpace 0x60000382c840> (kCGColorSpaceICCBased; kCGColorSpaceModelMonochrome; Generic Gray Gamma 2.2 Profile; extended range)] ( 1 1 )>
(lldb) po self.view.layer.description
<CALayer: 0x600001c3c760>
(lldb) po self.view.layer.debugDescription
<CALayer:0x600001c3c760; name = "VC:ViewController"; position = CGPoint (207 368); bounds = CGRect (0 0; 414 736); delegate = <UIView: 0x7fe813c09da0; frame = (0 0; 414 736); autoresize = W+H; layer = <CALayer: 0x600001c3c760>>; allowsGroupOpacity = YES; name = VC:ViewController; backgroundColor = <CGColor 0x600003f232f0> [<CGColorSpace 0x60000382c840> (kCGColorSpaceICCBased; kCGColorSpaceModelMonochrome; Generic Gray Gamma 2.2 Profile; extended range)] ( 1 1 )>
- 使用po命令修改值
(lldb) po self.titleLabel.text
快來占領(lǐng)榜單第一名吧
(lldb) po self.titleLabel.text = @"Test"
Test
(lldb) po self.titleLabel.text
Test
5.2 p
命令:
5.2.1 使用p
命令輸出所有成員信息
(lldb) p self
(Signals.MasterViewController) $R0 = 0x00007f9e03f05060 {
UIKit.UITableViewController = {
baseUIViewController@0 = {
baseUIResponder@0 = {
NSObject = {
isa = Signals.MasterViewController
}
}
_overrideTransitioningDelegate = nil
_view = 0x00007f9e04033400
_tabBarItem = nil
_navigationItem = 0x00007f9e03f03de0
_toolbarItems = nil
_title = nil
_nibName = 0x000060000044def0 "7bK-jq-Zjz-view-r7i-6Z-zg0"
_nibBundle = 0x000060000009d240 "/Users/sammylan/Library/Developer/CoreSimulator/Devices/B9ABA4CA-3F98-4607-898B-254D9351490C/data/Containers/Bundle/Application/D1011E4B-2BDF-4820-AC4B-E9DBE7EFC1CF/Signals.app"
_parentViewController = nil
_childModalViewController = nil
_parentModalViewController = nil
_previousRootViewController = nil
_modalTransitionView = nil
_modalPreservedFirstResponder = nil
_dimmingView = nil
_dropShadowView = nil
_currentAction = nil
_storyboard = 0x0000604000268740
_externalObjectsTableForViewLoading = 0x0000600000464940 2 key/value pairs
_topLevelObjectsToKeepAliveFromStoryboard = nil
_savedHeaderSuperview = nil
_savedFooterSuperview = nil
_editButtonItem = nil
_searchDisplayController = nil
_strongSearchDisplayController = nil
_modalTransitionStyle = 0
_modalPresentationStyle = 0
_lastKnownInterfaceOrientation = 0
_popoverController = nil
_containerViewInSheet = nil
_recordedContentScrollView = nil
_afterAppearance = nil
_explicitAppearanceTransitionLevel = 0
_interfaceBuilderKeyCommands = nil
_addedKeyCommands = nil
_overrideTraitCollectionsForChildren = nil
_previewSourceViews = nil
_retainCount = 18
_ignoreAppSupportedOrientations = false
_viewHostsLayoutEngine = false
_storyboardIdentifier = 0x0000604000269580 "UITableViewController-7bK-jq-Zjz"
_transitioningDelegate = nil
_frozenTraitCollection = nil
_overrideTraitCollection = nil
_accessibilityHUD = nil
overrideUseCustomPresentation = false
_modalPresentationCapturesStatusBarAppearance = false
_ignoresParentMargins = false
_childViewControllers = nil
_customNavigationInteractiveTransitionDuration = 0
_customNavigationInteractiveTransitionPercentComplete = 0
_customTransitioningView = nil
_lastNotifiedTraitCollection = nil
_presentationController = nil
_navigationControllerContentOffsetAdjustment = 0
_leftContentMargin = 0
_rightContentMargin = 0
_contentMargin = 0
_topLayoutGuide = nil
_bottomLayoutGuide = nil
_topBarInsetGuideConstraint = nil
_bottomBarInsetGuideConstraint = nil
_storyboardSegueTemplates = 0x000060000000d070 1 element
_segueResponsibleForModalPresentation = nil
_sourceViewControllerIfPresentedViaPopoverSegue = nil
_modalSourceViewController = nil
_expectedWindow = nil
_presentedStatusBarViewController = nil
_presentedUserInterfaceStyleViewController = nil
_edgesForExtendedLayout = 15
__childControllerToIgnoreWhileLookingForTransitionCoordinator = nil
_presentingFocusedItem = nil
_navigationInsetAdjustment = nil
_storyboardPreviewSegueTemplates = nil
_storyboardCommitSegueTemplates = nil
_storyboardPreviewingRegistrants = nil
__embeddedView = nil
__embeddingView = nil
__embeddedDelegate = nil
_originalPresentationController = nil
_temporaryPresentationController = nil
_preferredFocusedItem = nil
}
_tableViewStyle = 0
_keyboardSupport = nil
_staticDataSource = nil
_filteredDataSource = 0x000060000044d9e0
_filteredDataType = 0
}
detailViewController = nil
}
5.2.2 使用p
命令格式化輸出
兼容C的格式化輸出: https://sourceware.org/gdb/onlinedocs/gdb/輸出-格式.html
- x:十六進(jìn)制,如
p/x 10
- d:十進(jìn)制,如
p/x 10
- u:無符號(hào)十進(jìn)制數(shù)
- o:八進(jìn)制
- t:二進(jìn)制, 如
p/t 10
- a:地址,
- c:字符常數(shù)
- f:浮動(dòng)
- s:字符串
LLDB 提供的格式化輸出(取自):http://lldb.llvm.org/varformats.html
- B:布爾值
- b:二進(jìn)制
- y:字節(jié)
- Y:帶ASCII的字節(jié)
- c:字符
- C:可打印字符
- F:復(fù)雜浮動(dòng)
- s:c型管柱
- i:十進(jìn)制
- E:枚舉
- x:十六進(jìn)制
- f:浮動(dòng)
- o:八進(jìn)制
- O: 十進(jìn)制
- U:unicode16
- u:無符號(hào)十進(jìn)制數(shù)
- p:指針
5.3 Swift與Objective-C調(diào)試上下文
5.3.1 默認(rèn)調(diào)試上下文
在調(diào)試程序時(shí)有兩個(gè)調(diào)試上下文:非Swift調(diào)試上下文
和 Swift調(diào)試上下文
:
- 當(dāng)你在
Objective-C代碼
中停止時(shí),LLDB將使用非Swift(Objective-C)上下文
- 當(dāng)你在
Swift代碼
中停止暮胧,LLDB將使用Swift調(diào)試上下文
锐借。 - 如果您
突然停止調(diào)試器
问麸,默認(rèn)情況下LLDB將選擇Objective-C調(diào)試上下文
。
如在swift代碼中設(shè)置斷點(diǎn)并停下,執(zhí)行以下命令將出錯(cuò)
(lldb) po [UIApplication sharedApplication]
error: <EXPR>:3:16: error: expected ',' separator
[UIApplication sharedApplication]
^
,
5.3.2 指定調(diào)試上下文: expression -l
在swift調(diào)試上下文下,可以通過-l
命令指定上下文,如下:
(lldb) expression -l objc -O -- [UIApplication sharedApplication]
<UIApplication: 0x7fe7d2c015d0>
注意:po
被映射為expression-O-
,無法使用po
顯式指定上下文.
方然也可以使用swift語法打印相應(yīng)值:
(lldb) po UIApplication.shared
<UIApplication: 0x7fe7d2c015d0>
突然停止調(diào)試器,會(huì)默認(rèn)進(jìn)入非swift調(diào)試上下文,此時(shí)使用swift語法打印相應(yīng)值也會(huì)出錯(cuò),使用objective-c語法則會(huì)成功,如下:
(lldb) po UIApplication.shared
error: property 'shared' not found on object of type 'UIApplication'
(lldb) po [UIApplication sharedApplication]
<UIApplication: 0x7fe7d2c015d0>
(lldb) expression -l swift -O -- UIApplication.shared
<UIApplication: 0x7fe7d2c015d0>
5.4 用戶自定義變量
在調(diào)試的時(shí)候,可以創(chuàng)建一些變量供后面使用,注意:變量名必需是$開頭的,如下,直接創(chuàng)建變量(test
)無法給后面使用,需要$開頭的變量($test
)才能在后面繼續(xù)使用.
(lldb) po id test = [NSObject new]
(lldb) po test
error: use of undeclared identifier 'test'
(lldb) po id $test = [NSObject new]
(lldb) po $test
<NSObject: 0x60400000e7f0>
注意:在Objective-C上下文中創(chuàng)建的LLDB用戶自定義變量钞翔,轉(zhuǎn)到Swift上下文后严卖,不一定能正常工作(尚未實(shí)現(xiàn)的功能)
在swift調(diào)試上下文下,執(zhí)行p obj
后,會(huì)自動(dòng)生成一個(gè)簡短的LLDB用戶自定義變量,可以在后續(xù)使用,如下,生成了個(gè)簡短的$R0
變量
(lldb) p self
(Signals.MasterViewController) $R0 = 0x00007f9e03f05060 {
...
_nibName = 0x000060000044def0 "7bK-jq-Zjz-view-r7i-6Z-zg0"
...
(lldb) po $R0.nibName
? Optional<String>
- some : "7bK-jq-Zjz-view-r7i-6Z-zg0"
(lldb) p $R0.nibName
(String?) $R10 = "7bK-jq-Zjz-view-r7i-6Z-zg0"
(lldb) po $R10
? Optional<String>
- some : "7bK-jq-Zjz-view-r7i-6Z-zg0"
6. 線程與堆棧
6.1 xcode 單步調(diào)試基本命令
- 如上圖,從左到右依次為:
-
continue / pause
: 繼續(xù)運(yùn)行(或者遇到下一個(gè)斷點(diǎn)停止)/ 暫停運(yùn)行 -
step over
: 單步執(zhí)行,在函數(shù)內(nèi)遇到子函數(shù)時(shí)不會(huì)進(jìn)入子函數(shù). -
step into
: 單步執(zhí)行,遇到子函數(shù)就進(jìn)入并且繼續(xù)單步執(zhí)行. -
step out
: 在單步執(zhí)行到子函數(shù)內(nèi)時(shí),按step out
就可以執(zhí)行完子函數(shù)余下部分并返回上一層函數(shù).
- 指令級(jí)單步調(diào)試:
Ctrl +
按住Ctrl
執(zhí)行step over
或step into
功能,將執(zhí)行匯編指令級(jí)別的單步調(diào)試,按住Ctrl
+step into
可進(jìn)入無源碼函數(shù)進(jìn)行單步調(diào)試 - 多線程單步調(diào)試:
Ctrl + Shift
Ctrl + Shift
執(zhí)行step over
或step into
功能時(shí)將只單步調(diào)試當(dāng)前線程(其它線程進(jìn)入暫停狀態(tài))
6.2 查看堆棧信息
6.2.1 thread backtrace
: 查看堆棧信息
(lldb) thread backtrace
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 2.1
* frame #0: 0x000000010556d7c2 Signals`MasterViewController.viewDidLoad(self=0x00007fd887c0a9a0) at MasterViewController.swift:38:5
frame #1: 0x000000010556e03b Signals`@objc MasterViewController.viewDidLoad() at <compiler-generated>:0
frame #2: 0x000000010fe400f7 UIKitCore`-[UIViewController loadViewIfRequired] + 1183
frame #3: 0x000000010fe40524 UIKitCore`-[UIViewController view] + 27
frame #4: 0x00000001105dd4b5 UIKitCore`__67-[UIStoryboardEmbedSegueTemplate newDefaultPerformHandlerForSegue:]_block_invoke + 180
frame #5: 0x00000001105df4d3 UIKitCore`-[UIStoryboardSegueTemplate _performWithDestinationViewController:sender:] + 276
frame #6: 0x00000001105df391 UIKitCore`-[UIStoryboardSegueTemplate _perform:] + 82
frame #7: 0x00000001105df653 UIKitCore`-[UIStoryboardSegueTemplate perform:] + 157
frame #8: 0x000000010fe3fee3 UIKitCore`-[UIViewController loadViewIfRequired] + 651
frame #9: 0x000000010fe40524 UIKitCore`-[UIViewController view] + 27
frame #10: 0x000000010fdb1690 UIKitCore`-[UINavigationController preferredContentSize] + 197
frame #11: 0x000000010fdd745b UIKitCore`-[UIViewController(UIPopoverController_Internal) _resolvedPreferredContentSize] + 62
frame #12: 0x000000010fdde97f UIKitCore`-[UIPopoverController _transitionFromViewController:toViewController:animated:] + 141
frame #13: 0x000000010fdd7c0b UIKitCore`-[UIPopoverController _initWithContentViewController:popoverControllerStyle:] + 699
frame #14: 0x000000010fe1463b UIKitCore`-[UISplitViewControllerClassicImpl _setupHiddenPopoverControllerWithViewController:] + 188
frame #15: 0x000000010fe1323e UIKitCore`-[UISplitViewControllerClassicImpl _addOrRemovePopoverPresentationGestureRecognizer] + 121
frame #16: 0x000000010fe128db UIKitCore`-[UISplitViewControllerClassicImpl loadView] + 339
frame #17: 0x000000010fe3fd04 UIKitCore`-[UIViewController loadViewIfRequired] + 172
frame #18: 0x000000010fe40524 UIKitCore`-[UIViewController view] + 27
6.2.2 frame
命令: 棧幀操作
frame
常用命令
-
frame info
: 列出當(dāng)前棧幀信息 -
frame select
: 選擇某一層棧幀作為當(dāng)前棧幀 -
frame variable
: 查看當(dāng)前棧幀變量,默認(rèn)為展開方式輸出,-F
選項(xiàng)用平鋪方式輸出
(lldb) frame info
frame #0: 0x000000010556d7c2 Signals`MasterViewController.viewDidLoad(self=0x00007fd887c0a9a0) at MasterViewController.swift:38:5
(lldb) frame select 1
frame #1: 0x000000010556e03b Signals`@objc MasterViewController.viewDidLoad() at <compiler-generated>:0
(lldb) frame info
frame #1: 0x000000010556e03b Signals`@objc MasterViewController.viewDidLoad() at <compiler-generated>:0
(lldb) frame variable #默認(rèn)展開方式輸出
(Bool) animated = false
(Signals.MasterViewController) self = 0x00007f9d4fd076b0 {
UIKit.UITableViewController = {
baseUIViewController@0 = {
baseUIResponder@0 = {
baseNSObject@0 = {
isa = Signals.MasterViewController
}
}
# 其它未列出
(lldb) frame variable -F self # -F參數(shù),平鋪方式輸出
self = 0x00007f9d4fd076b0
self =
self.isa = Signals.MasterViewController
self._overrideTransitioningDelegate = nil
self._view = some
self._view.some = 0x00007f9d5a034000
self._view.some.isa = UITableView
# 其它未列出
- 詳細(xì)幫助信息如下:
(lldb) help fram
Commands for selecting and examing the current thread's stack frames.
Syntax: frame <subcommand> [<subcommand-options>]
The following subcommands are supported:
info -- List information about the current stack frame in the
current thread.
recognizer -- Commands for editing and viewing frame recognizers.
select -- Select the current stack frame by index from within the
current thread (see 'thread backtrace'.)
variable -- Show variables for the current stack frame. Defaults to all
arguments and local variables in scope. Names of argument,
local, file static and file global variables can be
specified. Children of aggregate variables can be specified
such as 'var->child.x'. The -> and [] operators in 'frame
variable' do not invoke operator overloads if they exist,
but directly access the specified element. If you want to
trigger operator overloads use the expression command to
print the variable instead.
It is worth noting that except for overloaded operators,
when printing local variables 'expr local_var' and 'frame
var local_var' produce the same results. However, 'frame
variable' is more efficient, since it uses debug
information and memory reads directly, rather than parsing
and evaluating an expression, which may even involve JITing
and running code in the target program.
For more help on any particular subcommand, type 'help <command> <subcommand>'.
6.1 LLDB中的 單步調(diào)試基本命令
Xcode | LLDB | 描述 |
---|---|---|
continue | continue | 繼續(xù)運(yùn)行(或者遇到下一個(gè)斷點(diǎn)停止) |
step over | next | 單步執(zhí)行,在函數(shù)內(nèi)遇到子函數(shù)時(shí)不會(huì)進(jìn)入子函數(shù). |
step into | step | 單步執(zhí)行,遇到子函數(shù)就進(jìn)入(有源碼才可以)并且繼續(xù)單步執(zhí)行. |
Ctrl + step into | step -a0 | 單步執(zhí)行,遇到子函數(shù)就進(jìn)入(無源碼也可以)并且繼續(xù)單步執(zhí)行. |
step out | finish | 執(zhí)行完當(dāng)前棧幀并返回上一層調(diào)用 |
-
continue / pause
: 繼續(xù)運(yùn)行(或者遇到下一個(gè)斷點(diǎn)停止)/ 暫停運(yùn)行 -
step over
: 單步執(zhí)行,在函數(shù)內(nèi)遇到子函數(shù)時(shí)不會(huì)進(jìn)入子函數(shù). -
step into
: 單步執(zhí)行,遇到子函數(shù)就進(jìn)入并且繼續(xù)單步執(zhí)行. -
step out
: 在單步執(zhí)行到子函數(shù)內(nèi)時(shí),按step out
就可以執(zhí)行完子函數(shù)余下部分并返回上
7. image: 進(jìn)程模塊信息
7.1 image
常用命令
-
image list
: 列出所有模塊信息, -
image list 模塊名
: 列出指定模塊信息 -
image dump symtab
: 輸出符號(hào)信息 -
image dump symtab 模塊名
:輸出特定模塊的符號(hào)信息 -
image lookup
:查找符號(hào)信息
(lldb) image list Foundation
[ 0] 30153EA5-45E2-334A-99DF-6E79D88AB4D0 0x000000010303d000 /Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 12.4.simruntime/Contents/Resources/RuntimeRoot/System/Library/Frameworks/Foundation.framework/Foundation
(lldb) image lookup -n "-[UIViewController viewDidLoad]"
1 match found in /Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 12.4.simruntime/Contents/Resources/RuntimeRoot/System/Library/PrivateFrameworks/UIKitCore.framework/UIKitCore:
Address: UIKitCore[0x000000000034cab5] (UIKitCore.__TEXT.__text + 3451269)
Summary: UIKitCore`-[UIViewController viewDidLoad]
(lldb) image dump symtab UIKit -s address
Symtab, file = /Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 12.4.simruntime/Contents/Resources/RuntimeRoot/System/Library/Frameworks/UIKit.framework/UIKit, num_symbols = 3 (sorted by address):
Debug symbol
|Synthetic symbol
||Externally Visible
|||
Index UserID DSX Type File Address/Value Load Address Size Flags Name
------- ------ --- --------------- ------------------ ------------------ ------------------ ---------- ----------------------------------
[ 0] 0 Data 0x0000000000000fd0 0x0000000104715fd0 0x0000000000000028 0x001e0000 UIKitVersionString
[ 1] 1 Data 0x0000000000000ff8 0x0000000104715ff8 0x0000000000000008 0x001e0000 UIKitVersionNumber
其中:
- 模塊的UUID: UUID對(duì)于尋找符號(hào)信息和唯一標(biāo)識(shí)基礎(chǔ)模塊,30153EA5-45E2-334A-99DF-6E79D88AB4D0
- 加載地址: 0x000000010303d000
- 模塊路徑: /Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 12.4.simruntime/Contents/Resources/RuntimeRoot/System/Library/Frameworks/Foundation.framework/Foundation
7.2 image lookup: 查找符號(hào)
-
image lookup -a
: 根據(jù)地址查找符號(hào)信息 -
image lookup -n
: 根據(jù)符號(hào)名字查找符號(hào)信息 -
image lookup -r
: 啟用正則表達(dá)式查找符號(hào)
image lookup -rn "UIViewController" ;查找UIViewController相關(guān)的全部符號(hào)
image lookup -rn "-\[UIViewController" ;查找UIViewController的實(shí)例方法
image lookup -rn "\+\[UIViewController"; 查找UIViewController的類方法
image lookup -rn "-\[UIViewController\sset" ; 查找UIViewController的所有set方法
image lookup -rn "-\[UIViewController\(\w+\)" 查找UIViewController的所有分類的方法
注意,以下字符需要轉(zhuǎn)義:
[
,]
,(
,)
,(空格,也可以用
\s
代替),+
,-
7.3 給所有Block下斷點(diǎn)
- 在一個(gè)Block中打斷點(diǎn),執(zhí)行到Block的時(shí)候,輸入以下命令查看Block的命名規(guī)范.block 都是包含
_block_invoke_
的函數(shù)調(diào)用
(lldb) frame info
frame #0: 0x000000010b9f1440 Commons`__34+[UnixSignalHandler sharedHandler]_block_invoke(.block_descriptor=0x000000010b9f9348) at UnixSignalHandler.m:68:28
- 查找特定模塊的所有Block:
image lookup -rn _block_invoke <模塊名>
(lldb) image lookup -rn _block_invoke Commons
6 matches found in /Users/sammylan/Library/Developer/Xcode/DerivedData/Signals-efbmlrmvuqjbiyfptsisstosyqdx/Build/Products/Debug-iphonesimulator/Signals.app/Frameworks/Commons.framework/Commons:
Address: Commons[0x0000000000004830] (Commons.__TEXT.__text + 1152)
Summary: Commons`__32-[UnixSignalHandler initPrivate]_block_invoke at UnixSignalHandler.m:78 Address: Commons[0x0000000000004430] (Commons.__TEXT.__text + 128)
Summary: Commons`__34+[UnixSignalHandler sharedHandler]_block_invoke at UnixSignalHandler.m:67 Address: Commons[0x0000000000004bc0] (Commons.__TEXT.__text + 2064)
Summary: Commons`__38-[UnixSignalHandler appendSignal:sig:]_block_invoke at UnixSignalHandler.m:119 Address: Commons[0x0000000000004c00] (Commons.__TEXT.__text + 2128)
Summary: Commons`__38-[UnixSignalHandler appendSignal:sig:]_block_invoke_2 at UnixSignalHandler.m:123 Address: Commons[0x0000000000004f70] (Commons.__TEXT.__text + 3008)
Summary: Commons`__38-[UnixSignalHandler appendSignal:sig:]_block_invoke_3 at UnixSignalHandler.m:135 Address: Commons[0x0000000000004a70] (Commons.__TEXT.__text + 1728)
Summary: Commons`__32-[UnixSignalHandler initPrivate]_block_invoke.24 at UnixSignalHandler.m:105
- 給特定模塊的所有Block下斷點(diǎn):
rb appendSignal.*_block_invoke -s Commons
該斷點(diǎn)是在Commons里的appendSignal函數(shù)下的所有Block下斷點(diǎn)
(lldb) rb appendSignal.*_block_invoke -s Commons
Breakpoint 6: 3 locations.
8 自定義命令及持久化"command alias
lldb 可以使用command alias
自定義命令
(lldb) help command alias
Define a custom command in terms of an existing command. Expects 'raw' input (see 'help raw-input'.)
Syntax: command alias <cmd-options> -- <alias-name> <cmd-name> [<options-for-aliased-command>]
Command Options Usage:
command alias [-h <help-text>] [-H <help-text>] -- <alias-name> <cmd-name> [<options-for-aliased-command>]
command alias <alias-name> <cmd-name> [<options-for-aliased-command>]
-H <help-text> ( --long-help <help-text> )
Long help text for this command
-h <help-text> ( --help <help-text> )
如
command alias -- Yay_Autolayout expression -l objc -O -- [[[[[UIApplication sharedApplication] keyWindow] rootViewController] view] recursiveDescription]
command alias cpo expression -l objc -O --
command alias sc script
command alias bp breakpoint
command alias bpl breakpoint list
command alias bcppfl breakpoint set -f %1.cpp -l %2
command alias bfl breakpoint set -f %1 -l %2
需要持久化的自定義命令需要保存到 ~/.lldbinit
.
~/.lldbinit
中新增的命令在LLDB中無法立刻使用,需要重啟LLDB或者執(zhí)行以下命令加載新增命令
(lldb) command source ~/.lldbinit
Executing commands in '/Users/sammylan/.lldbinit'.
(lldb) command alias -- Yay_Autolayout expression -l objc -O -- [[[[[UIApplication sharedApplication] keyWindow] rootViewController] view] recursiveDescription]
warning: Overwriting existing definition for 'Yay_Autolayout'.
command alias cpo expression -l objc -O --
command alias sc script
command alias bp breakpoint
command alias bpl breakpoint list
command alias bcppfl breakpoint set -f %1.cpp -l %2
command alias bfl breakpoint set -f %1 -l %2
輸入?yún)?shù)可以用%1,%2,...定義,可以直接在LLDB中使用自定義命令,如下:
(lldb) bfl KSDataNodeManager.m 30
Breakpoint 15: where = QQKSong`-[KSDataNodeManager init] + 36 at KSDataNodeManager.m:30:12, address = 0x0000000102fa0e8c
(lldb)
命令別名: command regex
我們發(fā)現(xiàn),無法使用command alias
給image lookup
提供別名,如:
(lldb) command alias rnlook image lookup -rn
(lldb) rnlook viewWillAppear
warning: Unable to find an image that matches 'lookup'.
這時(shí)候就需要用到 command regex
來定義別名,command regex
的語法如下:
regex <cmd-name> [s/<regex>/<subst>/ ...]
該命令定義<regex>
部分的內(nèi)容由
(lldb) help command regex
Define a custom command in terms of existing commands by matching regular expressions.
Syntax: command regex <cmd-name> [s/<regex>/<subst>/ ...]
Command Options Usage:
command regex [-h <none>] [-s <none>]
-h <none> ( --help <none> )
The help text to display for this command.
-s <none> ( --syntax <none> )
A syntax string showing the typical usage syntax.
給image lookup -rn
定義別名,如下
(lldb) command regex rlook 's/(.+)/image lookup -rn %1/'
(lldb) rlook viewWillAppear
2 matches found in /Users/sammylan/Library/Developer/Xcode/DerivedData/Signals-efbmlrmvuqjbiyfptsisstosyqdx/Build/Products/Debug-iphonesimulator/Signals.app/Signals:
Address: Signals[0x0000000100004050] (Signals.__TEXT.__text + 3216)
Summary: Signals`Signals.MasterViewController.viewWillAppear(Swift.Bool) -> () at MasterViewController.swift:51 Address: Signals[0x0000000100004780] (Signals.__TEXT.__text + 5056)
Summary: Signals`@objc Signals.MasterViewController.viewWillAppear(Swift.Bool) -> () at <compiler-generated>
命令速查
查看內(nèi)存 x
x/nuf <addr>
n 表示要顯示的內(nèi)存單元的個(gè)數(shù)
------------------------
u 表示一個(gè)地址單元的長度
b 表示單字節(jié)
h 表示雙字節(jié)
w 表示4字節(jié)
g 表示8字節(jié)
------------------------
f 表示顯示方式趟济,可取以下值:
x 按十六進(jìn)制格式顯示變量
d 按十進(jìn)制格式顯示變量
u 按十進(jìn)制格式顯示無符號(hào)整型
o 按八進(jìn)制格式顯示變量
t 按二進(jìn)制格式顯示變量
a 按十六進(jìn)制格式顯示變量
i 按指令地址格式顯示變量
c 按字符格式顯示變量
f 按浮點(diǎn)數(shù)格式顯示變量