iOS開發——測試篇&breakpoints、lldb 和 chisel 的詳解

來源:互聯網
上載者:User

標籤:

breakpoints、lldb 和 chisel 的詳解  

 

 

 

Breakpoints

BreakPoint分類

breakpoint也是有分類的,我這裡的文章內大致按使用的方式分為了

  • Normal Breakpoint,
  • Exception Breakpoint,
  • OpenGL ES Error breakpoint,
  • Symbolic Breakpoint,
  • Test Failure Breakpoint,
  • WatchPoints。

 

可以按具體的情景使用不同類型的breakpoint,解決問題為根本。

Normal Breakpoint

添加普通斷點就不多說了,在原始碼的右側點擊一下即可。或者,使用快速鍵:command + \ 來添加和刪除。這兩種方式添加的breakpoints在Xcode上面是可以通過UI看到的。

還有可以通過下面兩個LLDB命令直接在運行時添加斷點,但是這種方式需要注意的是一方面無法通過UI直接看到斷點,另外一方面只存在於本次運行,下一次啟動模擬器重新啟動並執行時候,這些斷點就不生效了。

如,通過“br li”命令列印所有的breakpoint,可以看到一共有3個breakpoint,第一個是通過Xcode的UI添加的,後面兩個分別是通過下面兩個命令添加的:

“breakpoint set -f XXX.m -l XX” 和  “b XXX.m:XX”。

Exception Breakpoint

可以通過中Xcode的UI添加Exception Breakpoint。有時候,比如數組越界或者設定一個Null 物件等問題,都會拋出一個異常,但是這種類型的錯誤非常難以定位,這個時候就可以使用Exception Breakpoint來進行調試,在異常發生時可以捕捉到並停止程式的執行。OC中的異常是一個常被忽略的地方,但實際上系統架構內這個使用非常廣泛,大部分這種錯誤資訊,系統架構都會以異常的形式throw出來,所以善用這種breakpoint的話,我們能大大減少尋找錯誤的時間。

例如,當我們添加如下Exception Breakpoint之後(bt 命令後文中會講解,這個命令的作用是在斷點觸發時,列印回調棧資訊):

類似下面這樣的數組越界的問題,我們可以很容易就定位到問題所在,不用再毫無頭緒找來找去了:

當斷點暫停執行時,我們可以通過Xcode的UI中查看調用棧資訊:

或者查看bt命令列印的調用棧資訊:

還有類似如下的錯誤可以通過這種斷點很容易定位到:

,不過這種問題,可以通過使用setValue:forKey:代替來避免。

OpenGL ES Error Breakpoint

同中,在Xcode的breakpoint navigator的下部添加按鈕,選擇”Add OpenGL ES Error Breakpoint”即可。這個breakpoint主要是用來在OpenGL ES發生錯誤時停止程式的運行。

Symbolic Breakpoint

通過Xcode的UI添加symbolic breakpoint的方式同exception breakpoint,彈出框如下:

Symbolic breakpoints 在某個特定的函數或者方法開始執行的時候,暫停程式的執行,通過這種方式添加斷點,我們就不需要知道在源檔案中添加,也不需要知道斷點設定在檔案的第幾行。

中,最主要的設定是Symbol的內容,可以有如下幾種:

  • 1. A method name,方法名稱,例如 pathsMatchingExtensions: 這樣的方法名稱,會對所有類的這個方法都起作用。
  • 2. A method of a particular class. 特定類的某個方法。例如 ,[SKLine drawHandlesInView],或者 people::Person::name()
  • 3. A function name。函數名稱。例如 ,_objc_msgForward 這樣C函數。

另外,也可以通過命令列的方式添加 Symbolic breakpoints。對C函數添加斷點:

對OC的方法添加斷點:

常用的這個類型的斷點有,objc_exception_throw可以用來代替 Exception Breakpoint,還有一個-[NSObject doesNotRecognizeSelector:] 也比較常用,用於檢測方法調用失敗。

Test Failure Breakpoint

通過Xcode的UI添加方法同上。這個類型的break point 會在 test assertion 失敗的時候暫停程式的執行。

Watchpoints

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

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

命令列

或者也可以通過命令列來設定watchpoint:watch set variable _button1ClickCount,詳細命令可以參考:http://lldb.llvm.org/lldb-gdb.html,有好幾種命令可以達到同樣的效果。

上面是對變數進行觀察,實際上我們可以對任意記憶體位址進行觀察,命令如下:watchpoint set expression — 0x123456,參考:http://stackoverflow.com/questions/21063995/watch-points-on-memory-address

需要注意的是,watchpoint是分類型的,包括read,write或者read_write類型,這個非常容易理解,在讀,寫或者讀寫變數或記憶體的時候,watchpoint是否被觸發。read,write或read_write跟著-w參數後面表示類型。另外,命令列中,watchpoint還有一些簡寫,set簡寫為s,watch簡寫為wa,variable簡寫為v。

下面的樣本是來自 http://www.dreamingwish.com/article/lldb-usage-a.html 網站的幾個命令:

第一個命令是監聽_abc4變數的記憶體位址write的變化,第二個是監聽_abc4變數read的變化,第三個是監聽_abc3變數read_write的變化。

需要注意的是,通過Xcode的GUI添加的watchpoint為預設類型,即write類型,如果想要添加讀寫都watch的watchpoint,則只能通過命令列工具進行添加了。

使用watchpoint modify -c ‘(XXX==XX)’,則修改watchpoint之後在某個值的時候才會監聽。

編輯選項

BreakPoint Condition

當我們通過Xcode對breakpoint進行編輯時,可以發現normal breakpoint和symbolic breakpoint都有一個”Condition”輸入選項,這個的作用很容易理解,只有在設定的condition運算式為YES的情況下這些斷點才會起作用。

例如,中的breakpoint在判斷字串相等的時候才會停止運行:

可以注意到這裡使用stringWithUTF8Stirng:方法,原因在於lldb的expression parser有一個bug,不相容非ASCII字元,需要處理一下才行,否則會報錯“An Objective-C constant string‘s string initializer is not an array”,參考:http://stackoverflow.com/questions/17192505/error-in-breakpoint-condition

更加簡單一些的例子就不說了,比如 i == 99之類的簡單比較,只要運算式的結果為BOOL類型即可。

Breakpoint Actions

可以看到上面的每種breakpoint編輯選項中基本上都有“Add Action”選項,當breakpoint被觸發時,都首先會執行我們設定的這些action,然後我們才能得到控制權,即Xcode上面才會顯示程式停止執行的UI。這個Action通過例子比較好理解,我們通過上面那個setObject:forKey:的異常來說明。代碼如下:

設定Breakpoint:

可以看到中,我們一共設定了3個action。第一個action,用來列印exception的詳細資料,用法參考:http://stackoverflow.com/questions/17238673/xcode-exception-breakpoint-doesnt-print-details-of-the-exception-being-thrown。

第二個action,我們使用shell命令“say”,讓電腦發聲,把一段文字讀出來。

第三個action,我們使用“bt”命令來列印調用棧資訊

設定完成之後,當異常發生時,我們會聽到電腦發聲念中的英文,然後在log中可以看到如下資訊,第一行是Exception的描述資訊,下面是呼叫堆疊:

Continuing after Evaluation

看一下breakpoint的編輯彈窗,我們可以發現有一個 “Automatically continue after evaluation actions” checkbox選項。當我們勾選這個checkbox之後,debugger會執行breakpoint中添加的所有的actions,然後繼續執行程式。對於我們來說,除了觸發一大堆command並且執行時間很長的情況之外,程式會很快跳過這個breakpoint,所以我們可能根本不會注意到這個breakpoint的存在。所以,這個選項的功能相當於在執行的最後一個action之後,直接輸入continue命令繼續執行。

有了這個很強大的功能,我們可以直接通過breakpoints來單獨對我們的程式進行修改。在某行代碼時停止執行,使用”expression”命令來直接修改程式的某個變數設定直接修改UI,然後繼續執行。expression / call 配合這個選項的時候,會非常強大,可以很方便實現很多很強大的功能。

例如,我們實現一個如下的功能,把tableview的第一個cell的selectBackgroundView的背景色改為紅色:

action的內容為“expression [[cell selectedBackgroundView] setBackgroundColor:[UIColor redColor]]”,這裡的運算式先不用關心,我們後面LLDB章節會講到,修改之後,當我們點擊cell的時候,cell的背景就會如一樣變紅:

使用這種方式,我們在不需要修改一行代碼的情況下,只需要通過修改breakpoint,就可以實現對UI的各種調試效果。

 

iOS開發——測試篇&breakpoints、lldb 和 chisel 的詳解

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.