XCode 內置GDB,咱們能夠在命令行中使用 GDB 命令來調試咱們的程序。下面將介紹一些經常使用的命令以及調試技巧。app
po 命令:爲 print object 的縮寫,顯示對象的文本描述(顯示從對象的 description 消息得到的字符串信息)。iphone
好比:函數
上圖中,我使用 po 命令顯示一個 NSDictionary 的內容。注意在左側咱們能夠看到 dict 的一些信息:3 key/value pairs,顯示該 dict 包含的數據量,而展開的信息顯示 isa 層次體系(即class 和 metaclass結構關係)。咱們能夠右擊左側的 dict,選中「Print Description of "dict"」,則能夠在控制檯輸出 dict 的詳細信息:工具
[cpp] view plaincopyprint?ui
Printing description of dict: spa
<CFBasicHash 0x1001149e0 [0x7fff7e27ff40]>{type = immutable dict, count = 3, 命令行
entries => debug
0 : <CFString 0x100002458 [0x7fff7e27ff40]>{contents = "first"} = <CFString 0x100002438 [0x7fff7e27ff40]>{contents = "one"} 3d
1 : <CFString 0x100002498 [0x7fff7e27ff40]>{contents = "second"} = <CFString 0x100002478 [0x7fff7e27ff40]>{contents = "two"} 調試
2 : <CFString 0x1000024d8 [0x7fff7e27ff40]>{contents = "third"} = <CFString 0x1000024b8 [0x7fff7e27ff40]>{contents = "three"}
}
(gdb)
print 命令:有點相似於格式化輸出,能夠輸出對象的不一樣信息:
如:
[cpp] view plaincopyprint?
(gdb) print (char *)[[dict description] cStringUsingEncoding:4]
$1 = 0x1001159c0 "{\n first = one;\n second = two;\n third = three;\n}"
(gdb) print (int)[dict retainCount]
$2 = 1
(gdb)
注:4是 NSUTF8StringEncoding 的值。
info 命令:咱們能夠查看內存地址所在信息
好比 "info symbol 內存地址" 能夠獲取內存地址所在的 symbol 相關信息:
[cpp] view plaincopyprint?
(gdb) info symbol 0x00000001000017f7
main + 343 in section LC_SEGMENT.__TEXT.__text of /Users/LuoZhaohui/Library/Developer/Xcode/DerivedData/RunTimeSystem-anzdlhiwvlbizpfureuvenvmatnp/Build/Products/Debug/RunTimeSystem
好比 "info line *內存地址" 能夠獲取內存地址所在的代碼行相關信息:
[cpp] view plaincopyprint?
(gdb) info line *0x00000001000017f7
Line 62 of "/Users/LuoZhaohui/Documents/Study/RunTimeSystem/RunTimeSystem/main.m" starts at address 0x1000017f7 <main+343> and ends at 0x10000180a <main+362>.
show 命令:顯示 GDB 相關的信息。如:show version 顯示GDB版本信息
[cpp] view plaincopyprint?
(gdb) show version
GNU gdb 6.3.50-20050815 (Apple version gdb-1708) (Mon Aug 8 20:32:45 UTC 2011)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "x86_64-apple-darwin".
help 命令:若是忘記某條命令的語法了,可使用 help 命令名 來獲取幫助信息。如:help info 顯示 info 命令的用法。
[cpp] view plaincopyprint?
(gdb) help info
Generic command for showing things about the program being debugged.
List of info subcommands:
info address -- Describe where symbol SYM is stored
info all-registers -- List of all registers and their contents
info args -- Argument variables of current stack frame
info auxv -- Display the inferior's auxiliary vector
info breakpoints -- Status of user-settable breakpoints
info catch -- Exceptions that can be caught in the current stack frame
info checkpoints -- Help
info classes -- All Objective-C classes
......
Type "help info" followed by info subcommand name for full documentation.
Command name abbreviations are allowed if unambiguous.
(gdb)
在系統拋出異常處設置斷點
有時候咱們的程序不知道跑到哪一個地方就 crash 了,而 crash 又很難重現。保守的作法是在系統拋出異常以前設置斷點,具體來講是在 objc_exception_throw處設置斷點。設置步驟爲:首先在 XCode 按 CMD + 6,進入斷點管理窗口;而後點擊右下方的 +,增長新的 Symbolic Breakpoint,在 Symbol 一欄輸入:objc_exception_throw,而後點擊 done,完成。 這樣在 Debug 模式下,若是程序即將拋出異常,就能在拋出異常處中斷了。好比在前面的代碼中,我讓 [firstObjctcrashTest]; 拋出異常。在 objc_exception_throw 處設置斷點以後,程序就能在該代碼處中斷了,咱們從而知道代碼在什麼地方出問題了。
一、使用殭屍變量(NSZombieEnabled)
二、重寫object的respondsToSelector方法
在iphone開發的時候EXC_BAD_ACCESS這個bug時不容易找到緣由的。
首先說一下EXC_BAD_ACCESS 這個錯誤,能夠這麼說,90%的錯誤來源在於對一個已經釋放的對象進行release操做,或者操做一個在循環代碼中被修改的序列中的對象。雖然使用NSZombieEnabled變量能夠幫助你找到問題所在,但有的時候,即便經過設置NSZombieEnabled變量,仍是不能定位到問題所在,這個時候,你能夠試試重寫object的respondsToSelector方法,顯示出現EXEC_BAD_ACCESS前訪問的最後一個object,下面是具體的步驟:
a、在每一個類而且在 other c flags中加入-D _FOR_DEBUG_(記住請只在Debug Configuration下加入此標記)。這樣當你程序崩潰時,Xcode的console上就會準確地記錄了最後運行的object的方法。的實現文件(.m,.mm)文件中,添加以下代碼:
[cpp]
-(BOOL) respondsToSelector : (SEL)aSelector {
printf("SELECTOR: %s\n", [NSStringFromSelector(aSelector) UTF8String]);
return [super respondsToSelector:aSelector];
}
b、而且在 other c flags中加入-D _FOR_DEBUG_(記住請只在Debug Configuration下加入此標記)。這樣當你程序崩潰時,Xcode的console上就會準確地記錄了最後運行的object的方法。
三、讓XCode反饋足夠多的信息
在Edit–>Scheme裏面 找到Arguments ,在Environment Variables這裏添加
把下面2個值設置成YES
NSAutoreleaseFreedObjectCheckEnabled
NSDebugEnabled
這種方法很是好用,建議在創建一個工程的時候,加入此設置
四、設置全局異常斷點
在程序拋出異常時候,每每須要定位到異常
鍵入快捷鍵 cmd + 6 進入斷點窗口,點擊左下角的"+"按鈕,選擇彈出框的「Add Exception BreakPoint」項,以下圖所示:
而後使用默認設置,點擊"done"按鈕,設置全局異常斷點就完成了