http://blog.sina.com.cn/s/blog_6dce99b10101gwwv.html
http://www.tuicool.com/articles/fIR3U3
1. 運(yùn)行時(shí)修改變量的值
expr a = 5
2. xcode 拋出異常時(shí)候可以用$eax
“$eax”是cup的一個(gè)寄存器。在一個(gè)異常的情況下,這個(gè)寄存器將會(huì)包含一個(gè)異常對(duì)象的指針。注意:$eax只會(huì)在模擬器里面工作,假如你在設(shè)備上調(diào)試,你將需要使用”$r0″寄存器。
例如,假如你輸入:
(lldb) po [$eax class]
你將會(huì)看像這樣的東西:
(id) $2 = 0x01446e84 NSException
這些數(shù)字不重要,但是很明顯的是你正在處理的NSException對(duì)象在這里。
你可以對(duì)這個(gè)對(duì)象調(diào)用任何方法。例如:
(lldb) po [$eax name]
這個(gè)將會(huì)輸出這個(gè)異常的名字,在這里是NSInvalidArgumentException,并且:
(lldb) po [$eax reason]
這個(gè)將會(huì)輸出錯(cuò)誤消息:
(unsigned int) $4 = 114784400 Receiver () has no segue with identifier 'ModalSegue'
注意:當(dāng)你僅僅使用了“po $eax”,這個(gè)命令將會(huì)對(duì)這個(gè)對(duì)象調(diào)用“description”方法和打印出來,在這個(gè)情況下,你也會(huì)得到錯(cuò)誤的消息。
3. 什么時(shí)候用命令 P
例如想打印integer類型的變量或者方法返回值得時(shí)候
p (int)[[[self view] subviews] count]
得到的輸出是
(int) $2 = 2
細(xì)心的朋友可能會(huì)發(fā)現(xiàn)輸出的信息中帶有 $1 、 $2 的字樣。實(shí)際上,我們每次查詢的結(jié)果會(huì)保存在一些持續(xù)變量中($[0-9]+),這樣你可以在后面的查詢中直接使用這些值。比如現(xiàn)在我接下來要重新取回 $1 的值:
(lldb) po $1
(UIView *) $1 = 0x0824c800 <UITableView: 0x824c800; frame = (0 20; 768 1004); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x74c3010>; layer = <CALayer: 0x74c2710>; contentOffset: {0, 0}>
4. 命令call
call即是調(diào)用的意思。其實(shí)上述的po和p也有調(diào)用的功能。因此一般只在不需要顯示輸出,或是方法無返回值時(shí)使用call。 和上面的命令一樣,我們依然在 viewDidLoad: 里面設(shè)置斷點(diǎn),然后在程序中斷的時(shí)候輸入下面的命令:
call [self.view setBackgroundColor:[UIColor redColor]]
繼續(xù)運(yùn)行程序,看看view的背景顏色是不是變成紅色的了!在調(diào)試的時(shí)候靈活運(yùn)用call命令可以起到事半功倍的作用。
5. 命令bt 或者bt all
打印調(diào)用堆棧,加all可打印所有thread的堆棧。
6. 命令image
image 命令可用于尋址,有多個(gè)組合命令。比較實(shí)用的用法是用于尋找棧地址對(duì)應(yīng)的代碼位置。 下面我寫了一段代碼
NSArray *arr=[[NSArray alloc] initWithObjects:@"1",@"2", nil];
NSLog(@"%@",arr[2]);
這段代碼有明顯的錯(cuò)誤,程序運(yùn)行這段代碼后會(huì)拋出下面的異常:
*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayI objectAtIndex:]: index 2 beyond bounds [0 .. 1]'
*** First throw call stack:
(
0 CoreFoundation 0x0000000101951495 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x00000001016b099e objc_exception_throw + 43
2 CoreFoundation 0x0000000101909e3f -[__NSArrayI objectAtIndex:] + 175
3 ControlStyleDemo 0x0000000100004af8 -[RootViewController viewDidLoad] + 312
4 UIKit 0x000000010035359e -[UIViewController loadViewIfRequired] + 562
5 UIKit 0x0000000100353777 -[UIViewController view] + 29
6 UIKit 0x000000010029396b -[UIWindow addRootViewControllerViewIfPossible] + 58
7 UIKit 0x0000000100293c70 -[UIWindow _setHidden:forced:] + 282
8 UIKit 0x000000010029cffa -[UIWindow makeKeyAndVisible] + 51
9 ControlStyleDemo 0x00000001000045e0 -[AppDelegate application:didFinishLaunchingWithOptions:] + 672
10 UIKit 0x00000001002583d9 -[UIApplication _handleDelegateCallbacksWithOptions:isSuspended:restoreState:] + 264
11 UIKit 0x0000000100258be1 -[UIApplication _callInitializationDelegatesForURL:payload:suspended:] + 1605
12 UIKit 0x000000010025ca0c -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 660
13 UIKit 0x000000010026dd4c -[UIApplication handleEvent:withNewEvent:] + 3189
14 UIKit 0x000000010026e216 -[UIApplication sendEvent:] + 79
15 UIKit 0x000000010025e086 _UIApplicationHandleEvent + 578
16 GraphicsServices 0x0000000103aca71a _PurpleEventCallback + 762
17 GraphicsServices 0x0000000103aca1e1 PurpleEventCallback + 35
18 CoreFoundation 0x00000001018d3679 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 41
19 CoreFoundation 0x00000001018d344e __CFRunLoopDoSource1 + 478
20 CoreFoundation 0x00000001018fc903 __CFRunLoopRun + 1939
21 CoreFoundation 0x00000001018fbd83 CFRunLoopRunSpecific + 467
22 UIKit 0x000000010025c2e1 -[UIApplication _run] + 609
23 UIKit 0x000000010025de33 UIApplicationMain + 1010
24 ControlStyleDemo 0x0000000100006b73 main + 115
25 libdyld.dylib 0x0000000101fe95fd start + 1
26 ??? 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
現(xiàn)在,我們懷疑出錯(cuò)的地址是0x0000000100004af8(可以根據(jù)執(zhí)行文件名判斷,或者最小的棧地址)。為了進(jìn)一步精確定位,我們可以輸入以下的命令:
image lookup --address 0x0000000100004af8
命令執(zhí)行后返回:
我們可以看到,出錯(cuò)的位置是 RootViewController.m 的第53行。
Address: ControlStyleDemo[0x0000000100004af8] (ControlStyleDemo.__TEXT.__text + 13288)
Summary: ControlStyleDemo`-[RootViewController viewDidLoad] + 312 at RootViewController.m:53
7. 簡(jiǎn)稱和別名
很多時(shí)候,LLDB完整的命令是很長(zhǎng)的。比如前面所說的 image lookup --address 這個(gè)組合命令。為了方便日常的使用,提高效率,LLDB命令也提供通過簡(jiǎn)稱的方式調(diào)用命令。還是這個(gè)命令,我們用簡(jiǎn)稱就可以寫為 im loo -a ,是不是簡(jiǎn)單多了。
如果你是從gdb時(shí)代就開始使用調(diào)試器的,你會(huì)發(fā)現(xiàn),有些命令如 p 、 call 等命令和gdb下是一致的。其實(shí)這些命令是LLDB一些命令的別名,比如 p 是 frame variable 的別名, p view 實(shí)際上是 frame variable view 。除了系統(tǒng)自建的LLDB別名,你也可以自定義別名。比如下面這個(gè)命令
command alias ioa image lookup --address %1
是將我前面所介紹過的一個(gè)命令 image lookup --address 添加了一個(gè) ioa 的別名。然后執(zhí)行下面的命令:
(lldb) ioa 0x0000000100004af8
Address: ControlStyleDemo[0x0000000100004af8] (ControlStyleDemo.__TEXT.__text + 13288)
Summary: ControlStyleDemo`-[RootViewController viewDidLoad] + 312 at RootViewController.m:53
8. 常見問題
上面我們簡(jiǎn)單的學(xué)習(xí)了如何使用LLDB命令。但有時(shí)我們?cè)谑褂眠@些LLDB命令的時(shí)候,依然可能會(huì)遇到一些問題。比如下面這個(gè)命令。
(lldb) p NSLog(@"%@",[self.view viewWithTag:1001])
error: 'NSLog' has unknown return type; cast the call to its declared return type
error: 1 errors parsing expression
如果在使用LLDB命令中發(fā)現(xiàn)有 unknown type 的類似錯(cuò)誤(多見于id類型,比如NSArray中某個(gè)值),那我們就必須顯式聲明類型。比如上面這個(gè)命令,我們得這么修改。
p (void)NSLog(@"%@",[self.view viewWithTag:1001])
