應用調試:
1
xcode gdb/lldb調試指令
指令 解釋
break NUM 在指定的行上設定斷點。
bt 顯示所有的調用棧幀。該指令可用來顯示函數的調用順序。
clear 删除設定在特定源檔案、特定行上的斷點。其用法為:clear FILENAME:NUM。
continue 繼續執行正在調試的程式。該指令用在程式由于處理信号或斷點而導緻停止運作時。
display EXPR 每次程式停止後顯示表達式的值。表達式由程式定義的變量組成。
file FILE 裝載指定的可執行檔案進行調試。
help NAME 顯示指定指令的幫助資訊。
info break 顯示目前斷點清單,包括到達斷點處的次數等。
info files 顯示被調試檔案的詳細資訊。
info func 顯示所有的函數名稱。
info local 顯示當函數中的局部變量資訊。
info prog 顯示被調試程式的執行狀态。
info var 顯示所有的全局和靜态變量名稱。
kill 終止正被調試的程式。
list 顯示源代碼段。
make 在不退出 gdb 的情況下運作 make 工具。
next 在不單步執行進入其他函數的情況下,向前執行一行源代碼。
print EXPR 顯示表達式 EXPR 的值。
print-object 列印一個對象
print (int) name 列印一個類型
print-object [artist description] 調用一個函數
set artist = @"test" 設定變量值
whatis 檢視變理的資料類型
2
這裡記錄一下自己學習到的一些XCode調試的方法。這些調試方法可以讓我們使用XCode編寫代碼進行調試時用起來更順心應手。
XCode的調試方法包括運作時設定斷點,列印到控制台,手寫指令列印等。
1. 運作時設定斷點
在XCode中需要觀察的變量所在的代碼處添加斷點,可以讓程式運作到這裡暫停。這時滑鼠懸停在變量名處,XCode會顯示出該變量的資訊。
斷點的類型分為異常斷點(Exception Breakpoint)和符号斷點(Symbolic Breakpoint)等,在XCode斷點浏覽器(Breakpoints Navigator)的左下方可以添加這些斷點。
符号斷點中的符号可以指方法名稱或函數名稱。符号斷點可以中斷某個函數的調用。使用者還可以添加執行斷點的條件。

異常斷點可以使程式在每次發生異常時,都會被中斷。一般用來捕獲未知異常。
2. 列印到控制台
控制台位于XCode的底端,用于列印程式運作過程中的輸出資訊。在代碼中調用NSLog函數,可以列印變量值到控制台中顯示出來。
NSLog(@"obj:%@", obj);
需要特别注意的是,盡管NSLog可圈可點,但在實際應用中要防備其可能會引起安全問題,因為任何由NSLog輸出的内容都會成為應用程式成品代碼
的一部分,也就是說會被任何接觸到應用的人看到。隻要把裝置接入資訊管理工具,每個人都能檢視控制台資訊并查詢每一條日志記錄。這可能會引發一系列嚴重後
果,例如向控制台輸出機密邏輯算法或者使用者密碼等資訊。
我們可以使用宏來解決調用NSLog方法可能導緻的安全問題,隻在調試版本中調用NSLog。可以采用全局可通路的頭檔案,把所有日志記錄都灌進去,而且不用擔心它們會出現在成品代碼當中。
#ifdef DEBUG#define DMLog(...) NSLog(@"%s %@", __PRETTY_FUNCTION__, [NSString stringWithFormat:__VA_ARGS__])#else#define DMLog(...) do { } while (0)
現在如果我們使用DMLog(這個名稱可以随便起),它将隻向調試版本輸出結果,任何成品代碼都不會受到影響。PRETTY_FUNCTION也幫上了大忙,它會根據日志資訊來源為函數命名。
3. 在控制台端手寫指令列印
如果我們在應用的特定點進行中斷,一般來說是為了檢查對象的目前狀态。Xcode為我們提供了一套“variables view(變量視圖)”,該視圖位于Xcode底部,與控制台相鄰的左方區域。理論上講它的作用是顯示與目前環境相關的所有值的實時狀态,但在實踐中有時無法列出值,或者是并未将值更新為中斷時的最新狀态。幸運的是,我們可以利用一些非常實用的控制台(console)指令自己進行對象檢查工作。1
po 指令:為 print object 的縮寫,顯示對象的文本描述。使用p 指令來處理純量值,即原生類型(boolean、integer、float等)。
print 指令:有點類似于格式化輸出,可以輸出對象的不同資訊。
expr 表達式:列印表達式。
info 指令:我們可以檢視記憶體位址所在資訊。
info line *記憶體位址:可以擷取記憶體位址所在的代碼行相關資訊。
show 指令:顯示 GDB 相關的資訊。如:show version 顯示GDB版本資訊。
bt: 顯示目前程序的函數調用棧的情況;”up num”:檢視調用的詳細資訊;down:傳回棧清單;l:顯示詳細代碼資訊;p:輸出數值。
help 指令:如果忘記某條指令的文法了,用來擷取幫助資訊。
需要注意的是,上述這些都是GDB的調試指令,在LLDB中會有所差異。随着Xcode 5的釋出,LLDB調試器已經取代了GDB,成為了Xcode工程中預設的調試器。
這裡需要強調的一個技巧是,通過使用expr 表達式可實作在運作時修改變量的值。2
expr username = @"username"expr password = @"badpassword"
通過上面的代碼段,變量username和password分别被重新指派。
4. 設定NSZombieEnabled、MallocStackLogging、NSAutoreleaseFreedObjectCheckEnabled、NSDebugEnabled
第一種設定方法:
1. Product->Edit Scheme...->Run...->EnvironmentVariables.
2. add NSZombieEnabled,set the value with YES
3. add MallocStackLogging, set the value with YES.
4. add NSAutoreleaseFreedObjectCheckEnabled, set the value with YES.
5. add NSDebugEnabled, set the value with YES.
使用場景:
主要為了解決EXC_BAD_ACCESS問題,MallocStackLogging用來啟用malloc記錄(使用方式 malloc_history${App_PID}${Object_instance_addr})。
第二種設定方法:
直接通過Editing Scheme視窗中的Run選項下的Diagnostics頁籤來設定。
需要注意的問題:
NSZombieEnabled隻能在調試的時候使用,千萬不要忘記在産品釋出的時候去掉,因為NSZombieEnabled不會真正去釋放dealloc對象的記憶體。
5. 重寫respondsToSelector方法
實作方式
#ifdef _FOR_DEBUG_-(BOOL) respondsToSelector:(SEL)aSelector { printf("SELECTOR: %s\n", [NSStringFromSelector(aSelector) UTF8String]);return[super respondsToSelector:aSelector]; }#endif
使用方法:
需要在每個object的.m或者.mm檔案中加入上面代碼(應該可以使用類屬實作),并且在other c flags中加入-DFOR_DEBUG(記住請隻在Debug Configuration下加入此标記)。這樣當你程式崩潰時,XCode的console上就會準确地記錄了最後運作的object的方法。
http://mobile.51cto.com/iphone-377138.htm“iOS故障排除指南:基本技巧”
http://my.oschina.net/notting/blog/115294“Xcode LLDB Debug教程”
http://www.2cto.com/kf/201210/162934.html“Xcode調試攻略”
在本文中,我們的議題包括以下三點:
- 利用控制台檢查應用程式狀态;
- 進行日志記錄并深入掌握NSLog操作方法;
- 通過對象生命周期追蹤記憶體使用情況。
利用控制台進行檢查
位于Xcode底端的這位仁兄稱得上我們調試工作中的最佳助手。輸出日志資訊、錯誤資訊以及其它各類實用資訊都是它的拿手絕活,這有助于我們一步步鎖定應用錯誤。除了直接閱讀來自日志記錄的輸出結果,大家還可以在流程中的任意環節暫停,進而檢查應用程式的各個部分。
條件斷點
首先我假設大家已經了解存點的工作機制(如果還不了解也别擔心,看完這幾段内容您也應該基本掌握這部分知識了)。斷點的作用非常重要,它能夠幫我們 檢視應用程式在給定時間點上的所在位置——但在對象達到特定值并觸發斷點之後,再通過單步調試循環或者遞歸函數的做法實在是個痛苦的過程。這裡,我們推薦 大家采用條件斷點。
條件斷點,顧名思義是指隻會在特定條件下觸發的斷點。設想一下,當我們隻希望斷點在某對象在特定狀态或者“第n次”循環更替時發生,條件斷點就成為 大家的不二選擇。在Xcode編輯器中點選“gutter”來在代碼中添加一個斷點 ,右擊該斷點并選擇“edit breakpoint(編輯斷點)”為其設定特殊條件。
大家可以設定條件(例如i==12)或者設定循環中斷點被忽略的次數。當然,我們也可以采取其它一些自動觸發機制,例如在調試指令輸出值時啟用斷點。
提示: 利用快捷鍵組合coomand+\能夠快速添加或删除斷點。 |
另一項值得關注的斷點技巧是添加“exception breakpoint(異常斷點)”。不知道大家有沒有注意到,當我們遇到異常情況時,Xcode會有99%的機率将我們引向主方法中的自動釋放池。
感謝Xocde……你可真會幫倒忙。
通過設定異常斷點,我們就能夠精确定位引發異常情況的代碼行。要做到這一點,首先得打開異常斷點頁籤(快捷鍵為command+6)。在視窗底部 會出現一個“+”按鈕,點選該按鈕即可添加“異常斷點”。現在,一旦Xcode在運作中遭遇異常,即會在引發問題的代碼處中斷。
在控制台端實作手動輸出
如果我們在應用的特定點進行中斷,一般來說是為了檢查對象的目前狀态。Xcode為我們提供了一套“variables view(變量視圖)”,該視圖位于Xcode底部、與控制台相鄰。理論上講它的作用是顯示與目前環境相關的所有值的實時狀态。但在實踐中,這一作用有時 無法正常生效。或者是無法列出值,或者是并有将值更新為中斷時的最新狀态,總之問題不少。
幸運的是,我們可以利用一些非常實用的控制台指令自己進行對象檢查工作。在控制台中輸入“po”來擷取特定對象的目前細節資訊(我們使用‘p’來處理純量值)。
這種方式在檢查某對象是否已經存在(如果對象不存在則輸出結果為nil)、确定對象值、查詢某數組/字典在目前運作狀态下的内容以及對兩個對象進行 比較等方面效果拔群。由于這條指令會輸出相關對象的記憶體位址,是以我們可以對本應相同的兩個對象進行輸出,檢視二者是否正确擁有相同的記憶體位址。
另一條實用但卻常常被忽視的指令則是recursiveDescription,我們可以用它輕松檢查視圖。運作該指令後,系統會将視圖結構作為結果輸出。
有效日志記錄
在調試程式的過程中,大家常常希望能将特定消息記錄到控制台中。而“NSLog”函數允許使用者将任何想要的結果輸出至控制台。對于希望以特定途徑梳 理應用程式或者無法根據特定情況一一設定斷點卻仍然想要進行值比較的使用者而言,它的作用相當重要。NSLog的使用格式與[NSString StringWithFormat]相同(如下圖所示)。
1. Xcode内置GDB,可以使用GDB調試,調試指令:
1.1 po 指令:為 print object 的縮寫,顯示對象的文本描述
(lldb) po [$eax class]:輸出異常對象的位址
(lldb) po [$eax name]:輸出這個異常的名字
(lldb) po [$eax reason]:這個将會輸出錯誤消息:
(lldb) “po $eax”:對這個對象調用“description”方法和列印出來
“$eax”是cup的一個寄存器。在一個異常的情況下,這個寄存器将會包含一個異常對象的指針。注意:$eax隻會在模拟器裡面工作,假如你在裝置上調試,你将需要使用”$r0″寄存器
1.2 print 指令:有點類似于格式化輸出,可以輸出對象的不同資訊
比如:print (char*)[[dic description] cString]、(lldb) print (int)[label retainCount]
1.3 info 指令:我們可以檢視記憶體位址所在資訊
1.4 info line *記憶體位址:可以擷取記憶體位址所在的代碼行相關資訊
1.5 show 指令:顯示 GDB 相關的資訊。如:show version 顯示GDB版本資訊
1.6 bt: 顯示目前程序的函數調用棧的情況;"up num":檢視調用的詳細資訊;down:傳回棧清單;l:顯示詳細代碼資訊;p:輸出數值。
2. 添加全局斷點(Add Exception BreakPoint):
2.1 添加步驟:
1. In the bottom-left corner of the breakpoints navigator, click the Add button.
2. Choose Add Exception Breakpoint.
3. Choose the type of exception from the Exception pop-up menu.
4. Choose the phase of the exception handling process at which you want program execution to stop.
5. Click Done.
2.2 使用場景:
程式因為SIGABRT而crash,想要定位到導緻crash的行。
3. 添加符号斷點(Add Symbolic BreakPoint):
3.1 斷點執行的時機:Symbolic breakpoints stop program execution when a specific function or method starts executing
3.2 添加步驟:
1. Steps In the bottom-left corner of the breakpoint navigator, click the Add button.
2. Choose Add Symbolic Breakpoint.
3. Enter the symbol name in the Symbol field.
4. Click Done.
3.3 使用場景:
當想讓系統在某個指定條件處中斷時,設定相應的斷點。
比如:
objc_exception_throw:在系統抛出異常處設定斷點。
-[NSException raise]:
4. 設定NSZombieEnabled、MallocStackLogging、NSAutoreleaseFreedObjectCheckEnabled、NSDebugEnabled:
4.1 設定方法:
1. Product->Edit Scheme...->Run...->EnvironmentVariables.
2. add NSZombieEnabled,set the value with YES
3. add MallocStackLogging, set the value with YES.
4. add NSAutoreleaseFreedObjectCheckEnabled, set the value with YES.
5. add NSDebugEnabled, set the value with YES.
4.2 使用場景:
主要為了解決EXC_BAD_ACCESS問題,MallocStackLogging用來啟用malloc記錄(使用方式 malloc_history ${App_PID} ${Object_instance_addr})。
4.3 需要注意的問題
NSZombieEnabled隻能在調試的時候使用,千萬不要忘記在産品釋出的時候去掉,因為NSZombieEnabled不會真正去釋放dealloc對象的記憶體。
5. 重寫respondsToSelector方法
5.1 實作方式
[cpp]
#ifdef _FOR_DEBUG_
-(BOOL) respondsToSelector:(SEL)aSelector {
printf("SELECTOR: %s\n", [NSStringFromSelector(aSelector) UTF8String]);
return [super respondsToSelector:aSelector];
}
#endif
5.2 使用方法:
需要在每個object的.m或者.mm檔案中加入上面代碼(應該可以使用類屬實作),并且在other c flags中加入-D _FOR_DEBUG_(記住請隻在Debug Configuration下加入此标記)。這樣當你程式崩潰時,Xcode的console上就會準确地記錄了最後運作的object的方法。
參考文章:
1. Xcode GDB 調試:http://blog.csdn.net/ch_soft/article/details/7005998
2. XCode的一些調試技巧:http://blog.csdn.net/kesalin/article/details/7222153
3. About the Breakpoint Navigator:http://developer.apple.com/library/mac/#recipes/xcode_help-breakpoint_navigator/articles/about_breakpoint_navigator.html#//apple_ref/doc/uid/TP40010433-CH6-SW1
4. 當程式崩潰的時候怎麼辦 part-1:http://article.ityran.com/archives/1006
5. 當程式崩潰的時候怎麼辦 Part-2:http://article.ityran.com/archives/1143
6. Memory Usage Performance Guidelines:https://developer.apple.com/library/mac/#documentation /performance/Conceptual/ManagingMemory/ManagingMemory.html#//apple_ref/doc/uid/10000160-SW1
版權聲明:本文為CSDN部落客「weixin_34023863」的原創文章,遵循CC 4.0 BY-SA版權協定,轉載請附上原文出處連結及本聲明。
原文連結:https://blog.csdn.net/weixin_34023863/article/details/92317747