xcode調試技巧

轉自:http://www.cnblogs.com/LeeGof/p/5728672.html

Xcode 5的發佈,LLDB調試器已經取代了GDB,成爲了Xcode工程中默認的調試器。它與LLVM編譯器一起,帶給我們更豐富的流程控制和數據檢測的調試功能。LLDB爲Xcode提供了底層調試環境,其中包括內嵌在Xcode IDE中的位於調試區域的控制面板,在這裏我們可以直接調用LLDB命令,示例如下:

1.必備篇

1.1 打印變量:print/po

  • print:打印變量的值可以使用print命令,該命令如果打印的是簡單類型,則會列出簡單類型的類型和值。如果是對象,還會打印出對象指針地址;
  • print object:如果我們只想查看對象的值的信息,則可以使用po(print object的縮寫)命令。

1.2 查看線程狀態:thread list 

  在進程停止後,LLDB會選擇一個當前線程和線程中當前幀(frame)。很多檢測狀態的命令可以用於這個線程或幀。
  爲了檢測進程的當前狀態,使用該命令,其中星號(*)表示thread #1爲當前線程。

1.3 獲取線程的跟蹤棧:thread backtrace(簡寫bt)

  使用命令thread backtrace(簡寫bt)可以查看線程的跟蹤棧,若要查看所有線程的調用棧則可以使用命令:thread backtrace all (簡寫bt all)

1.4 列出幀參數和本地變量:frame variable 

  此處frame代指線程中當前幀(frame)

1.5 尋址:image

  image 我們可以用它來查找可執行文件或共享庫的原始地址,當我們的程序崩潰時,我們可以使用這條命令來查找崩潰所在的具體位置,如下所示:

  這段代碼在運行後會拋出如下異常:

  現在,我們懷疑出錯的地址是0x000000010ce22e42(可以根據執行文件名判斷,或者最小的棧地址)。爲了進一步精確定位,我們可以輸入以下的命令:image lookup --address

  可以看到,出錯的位置是 UserListViewController.m 的第206行

1.6 幫助系統:help

  LLDB幫助系統讓我們可以瞭解LLDB提供了哪些功能,並可以查看LLDB命令結構的詳細信息。熟悉幫助系統可以讓我們訪問幫助系統中中命令文檔。

  我們可以簡單地調用help命令來列出LLDB所有的頂層命令。

  如果help後面跟着某個特定的命令,則會列出該命令相關的所有信息,如下所示:

2.技巧篇

2.1 運行時修改變量的值:expression

  以前怎麼驗證是不是某個變量的值導致整段程序不能正常工作?修改代碼中的變量的值,然後cmd+r重新啓動app?現在你不需要這麼做了,只需要設置一個斷點,當程序在這進入調試模式後

使用 expression 命令即可在運行時修改變量的值

  命令執行完畢,繼續運行應用,會發現header背景顏色變爲黃色。該技巧實用於debug時改變某個label文字內容多少,查看顯示多行/單行效果。

2.2 異常排查:異常斷點

  如果添加了異常斷點,當程序每次發生了異常,都會被中斷。一般用來捕獲未知異常,運行效果如下

2.3 符號斷點

  symbolic breakpoint使用很簡單,點擊斷點界面的“+”號,選擇”Add Symbolic Breakpoint”就創建了一個斷點:

  下面開始最重要部分,斷點的可編輯項,如圖:

  從編輯界面可以看到斷點可編輯的項有Symbol、Module、Condition、Ignore、Action、Options

  • Symbol

  斷點觸發函數。有兩種函數寫法,一種是C函數樣式,一種是OC方法樣式。 
  C函數樣式只需要寫函數名,不用寫後面的()和參數。例如NSLog。 
  OC方法樣式的[className methodName] className是類名,methodName是方法名(不區分類方法和實例方法)。如果寫標記的這個類的方法被子類重寫了則子類的方法也會觸發斷點。例如[UIViewController viewDidLoad]。

  • Module

  模塊篩選。可以避免不同庫中方法名或者函數名相同。

  • Condition

  觸發條件。這裏可以添加一些指定觸發條件,比如添加第一個參數不能爲nil。這裏$arg3代表第1個參數,$arg4代表第2個參數,以此類推。這裏也可以調用方法來判斷,必須是類方法,並且返回值必須爲BOOL類型 

  示例:找出給[UIImage imageNamed:]傳nil的代碼。這裏就需要設置Symbol爲[UIImage imageNamed:],然後Condition設置爲$arg3 == nil。這樣在運行中如果遇到傳nil就會觸發斷點。

  • (4)Ignore

  觸發開始次數。設置這個值可以忽略前面指定次數的觸發。

  • (5)Action

  觸發活動。這裏是當斷點觸發後要執行的動作,可以添加多條,執行的順序是從上到下。一共有6種可執行類型,如下圖

  平時主要使用以下幾種:

  1. Debugger Command:會在斷點觸發的時候執行LLDB命令。可以打印對象、修改對象值等功能。
  2. Log Message:會在斷點觸發的時候打印日誌。其中@exp@打印對象值,exp爲對象名;%B表示斷點名;%H表示當前斷點觸發的次數。
  3. Shell Command:會在斷點觸發的時候執行Shell命令。
  • Options

  是否進入DEBUG界面。勾選這個斷點觸發後不進入DEBUG界面,斷點打印日誌或者聲音斷點一般都勾選。有時候我們的程序不知道跑到哪個地方就 crash 了,而 crash 又很難重現。保守的做法是在系統拋出異常之前設置斷點,具體來說是在 objc_exception_throw處設置斷點。這樣在 Debug 模式下,如果程序即將拋出異常,就能在拋出異常處中斷了。效果類似Exception breakpoint。

2.4 Watchpoints

  Watuchpoints是一個用來監聽變量的值的變化或者內存地址的變化的工具,發生變化時會在debugger中觸發一個暫停。對於那些不知道如何準確跟蹤的狀態問題,可以利用這個工具來解決。要設置watchpoint的話,在程序運行到stack frame包含有你想觀察的變量時,讓debugger暫停運行,這個時候變量在當前stack frame的scope內,這個時候才能對該變量設置watchpoint。

  你可以在Xcode的GUI中設置watchpoint,在xcode的 Variables View中,把你想觀察的變量保留出來,然後右鍵設置“Watch XXX”。例如下圖,觀察self的title變量,點擊 Watch “_button1ClickCount” 即可。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章