1. 程式人生 > >關於LLDB除錯你應該知道的

關於LLDB除錯你應該知道的

最近一直在與大家探討LLDB除錯的問題,最早是在objccn上看到--- 《與偵錯程式共舞-LLDB的華爾茲》,深深的吸引了我,所以就深入研究學習,果然用的人不是很多啊,不過還是找了幾篇不錯的文章,轉載來以供參考。

與偵錯程式共舞-LLDB的華爾茲  http://objccn.io/issue-19-2/

原文地址一:http://www.jianshu.com/p/f888db82fc27

原文地址二:http://www.jianshu.com/p/b2371dd4443b


久違的的LLDB篇一,讓lldb提升你的效率

本來一直想給大家普及一下lldb的使用,因為身邊有很多朋友雖然開發了很久,但是還是不會使用偵錯程式,還傻傻的打一個log,重啟程式再看這個值。說,是不是你,中招沒。這一篇也是為了幫這些朋友認識一下偵錯程式的強大。整篇介紹的例子都是基於我的貼圖demo的。

1.首先介紹下如何避免重啟程式打一個log

如圖下:

lldbLog
lldbLog
  • 1.首先註釋以前那該死的log背景被點選了,然後我加一個優美的斷點。
  • 2.然後右鍵點選斷點編輯斷點,首先選擇Action,logMessage,再點選+,選擇DebugerCommander,然後這裡面的命令和右下角的lldb命令是完全一樣的,這個命令你隨意打。
  • 3.最重要的一步,一點要選擇automaticlly continue after evalating value,這個可以使得程式不會中斷繼續執行。

好吧,大家以後就可以告別這個該死的log,以後大家的consle就不出現那些亂七八糟的log,而且還找不到了.我現在就是每次看到專案裡一堆log就特別煩……(ps:這個……是shift+6打出來的哦),所以只要你想在輸出某一個值或者一句話看一個函式,是否呼叫,完全不需要多餘的重新執行一次程式。

2基本的lldb命令的介紹

大家一般知道的lldb命令一般是p,和po,其實我研究了一陣子最實用的也就這兩個lldb命令,但是大家一般都不知道用在什麼場合。

  • p命令的介紹,首先p是列印非物件的值,它是 e --的縮寫。如果使用它列印物件的話,那麼它會打印出物件的地址,如果列印非物件它一般會打印出基本變數型別的值。當然用它也可以申明一個變數譬如 p int $a = 10; (注lldb使用$在變數前來宣告為lldb內的名稱空間的)
  • po 命令,po 命令是我們最常用的命令因為在ios開發中,我們時刻面臨著物件(ps:但是我沒有物件,歡迎介紹),所以我們在絕大部分時候都會使用po。首先po這個命令會打印出物件的description描述。

好吧,macDown語法還是沒有完全搞明白,所以篇幅不是太好看(這個完全沒想這麼早出這篇部落格)

下面還是使用一副圖片來描述具體的過程吧。

po的使用
po的使用
  • 1.首先我在背景蒙層下了個斷點,程式中斷之後,我首先通過po 命令打出了【po self.view】然後打出了當前的self.view的描述。
  • 2.然後我通過self.view的description描述,然後找到手勢NSArry的地址我打印出了當前view上面有那些手勢。
  • 然後找到當前pinch的手勢,然後通過p 命令,將其強轉成UIPinchGesture,因為lldb有時無法確定其具體的型別,需要強轉,但是這個強轉不是必須的,需要你們自己根據情況來決定。
  • 當我們使用p 命令列印一個物件時,lldb內部會預設使用一個$加數字來記錄這個物件。
  • 這個$會一直存在,當這個物件還沒銷燬的時候,所以我們隨時可以通過這個變數來列印以前的值。我是通過【$61 view】找出pinch 作用的view.我們也可以使用p 命令得到一個這個view在lldb的記錄。



注意在使用lldb內部的變數$來記錄變數的時候,絕大部分的時候都沒有語法提示,所以你需要自己能準確的打印出方法的名字。我這裡一般,都是在當前編輯器中去打好方法,然後再拷貝到lldb處。


在使用lldb命令的時候,並非所有的命令都很常用,你可以通過在lldb中 列印 help 檢視所有的lldb命令,譬如breakpoint命令,這種命令完全可以通過Xcode UI介面加斷點,當然所有的xcode ui 介面加斷點本質也是通過lldb的命令的,這個一般使用者都不會太常用。

help命令
help命令

今天就先介紹到這裡,下一篇部落格我會介紹給大家如何使用開源的facebook的chisel,從安裝到以及在什麼場景下使用什麼命令,和常用的chisel命令有哪些。因為這個MarkDown還沒弄太熟悉,所以重頭戲在下一章。(ps:主要是markDown還沒用熟,我自己看著都不爽,所以下次會帶來更好的版本,和更詳細的介紹) 


LLdb篇2教你使用faceBook的chisel來提高除錯效率

這次真是久違的第二篇了,過年的時候一直在幫家裡帶孩子,順便用webStorm這個神器重新溫習了下前端的知識。然後最近剛來北京又是重感冒,又是找房子,整個來說coding還是寫部落格效率極低又苦不堪言。

首先如果使用lldb,最好你要學著使用chisel來提高效率,否則你會浪費很多的時間,除非你自己會寫python指令碼,自己封裝一些lldb的命令。

安裝chisel

chisel的安裝是十分簡單,它是在終端通過brew安裝的,具體可以點選連結參考github的安裝說明,唯一需要注意的一點就是命令列安裝完之後,它會在安裝完之後顯示出chisel的安裝地址path.在執行下面的命令時候要記得替換/path/to/fblldb.py這一塊。

# ~/.lldbinit
...  
command script import /path/to/fblldb.py
script fblldb.loadCommandsInDirectory('/magical/    
commands/')

如果安裝成功的話,那麼你就會看到如下圖的這些命令。

lldb help
lldb help

這裡大概會有30個命令吧,我記得我第一次裝的時候沒那麼多命令的,facebook又更新了很多。其實這些封裝的命令,就是使用python封裝了一下函式然後呼叫。凡是這些封裝的命令,你都可以通過多個lldb命令打出來,所以如果你會使用python的話,那麼你可以根據自己的使用習慣封裝一些常用的lldb命令。我使用了也有一段時間的chisel了,但是感覺並不是所有的命令都很常用,而且有寫使用的場景也不是很清楚,所以在這裡給大家普及一下,如果有謬誤,請大家及時指正。(ps:和大家說個快捷鍵,cmd+k快速清楚console的資訊。)

一般我們使用chisel的命令的時候,我們可以通過 help + chisel命令,譬如 help + pvc,得到如何具體使用這個命令,但是有時候你看了help資訊也不一定就會用呢。

image
image

pviews

這個命令是我最常使用的命令。它能夠幫助我們看到view的層級,即使我們並沒有觸發到一個斷點。操作如下:

pviews
pviews
  • 如圖我沒有設定任何斷點,只是點選控制檯的暫停圖示,就可以撥出lldb控制檯了。然後再這裡輸出pviews這個命令。
  • 然後這個命令主要可以看到當前的view層級,如果我們寫了一個控制元件沒有顯示。我們就可以通過這個命令來排查。
  • 排查首先看有沒有我們新增的這個view,如button,如果記憶體地址裡沒有這個button,說明沒有新增到view中(沒呼叫addSubview方法)
  • 然後可以看到這個button的地址,我們可以看到這個button的frame屬性,根據屬性判斷是否是位置或者大小不合適。
  • 再次,我們要看是否hidden被設定成了yes,如果設定了yes的話,在列印資訊中會打印出來。因為預設view的isHidden是no,所以沒被列印。
  • 最後如果是button可以檢查下是否設定了圖片,如果是view,就可以檢視下顏色是否與後面的控制元件一致,這就引入到了下一個命令border。

border&unborder

border
border

這個命令可以直接給border 新增邊框顏色和邊框的寬度,使用如下:

border 0x79ec3140 -c green -w 2

border這個命令常常在我們需要檢視邊框的邊緣的問題,常常用到,而且我們想要設定的直接在lldb中設定,完全不需要重新寫程式碼再次執行。我就是通過直接暫停程式,並且通過pviews命令找到的控制元件的地址,並且呼叫命令顯示的。當我們不需要的時候可以通過unborder這個命令去掉邊框。整個過程一氣呵成。

pinternals

pinternals
pinternals

這個命令就是打印出來的一個控制元件(id)型別的內部結構,詳細到令人髮指!甚至是你自定義的控制元件中的型別,譬如這個styleView就是我自定義的,內部有個iconView的屬性,其中的值它也會打印出來。好處,你們自己琢磨吧。(ps:這個demo,我會在下一篇部落格中放出來,下篇部落格是說transform的。

presponder

打印出一個集成於UIResponder控制元件的訊息傳遞鏈。

presponder
presponder

這個也方便我們瞭解訊息是如何傳遞的,列印的時候是倒敘列印的。

visualize

可以使用mac下的預覽app開啟我們的圖片UIImage, CGImageRef格式的圖片,甚至view和layer的圖片 。

visualize 0x79ec3140//或者變數名,此地址是id型別的

pclass

pclass可以打印出一個物件的繼承關係。

pclass
pclass

taplog

這個命令是模擬敲擊一下螢幕,並且打印出你敲擊螢幕時候事件接收的物件。

image
image

hide&show

hide命令可以直接隱藏一個物件,移除當前遮擋的物件便於你觀察後面的物件。show命令會讓它再次顯示出來。

bmessage

這個命令就是lldb新增一個斷點,譬如-viewWillAppear:這個方法,在當前控制器中你沒有實現它,但是你又想在呼叫它的時機觸發中斷。

Arguments:
<expression>; Type: string; Expression to set a breakpoint on, e.g. "-[MyView setFrame:]", "+[MyView awesomeClassMethod]" or "-[0xabcd1234 setFrame:]"

這個我就不解釋了,需要補充一點的是oc的方法是帶的。

其他命令

其它命令我用著並不是太多,並不代表他們不常用。只是我用的不太好而已,而且我認為用到是需要特殊的場景的,這個裡說幾個我感覺有很大作用但是我用的又不好的。

  1. wivar,這個命令是加watchPoint,用的好,就相當於使用lldb寫了kvo了。(ps:恕我沒研究明白)
  2. pvc這個命令的作用是打印出當前的控制器層級,(ps:有時好使,有時又很壞,似魔鬼的步伐.?,沒研究明白)
  3. vsfv,fvc,這幾個命令都需要正則表示式的知識背景,因為我正則表示式從來都是百度,也沒自己真正學過。所以對我不常用,但是對那些會正則的可能會很大作用。(ps:希望你們研究出來有什麼好的技巧分享下)

參考

我寫的這些關於lldb的東西只是九牛一毛,它可以做的事情特別多,上面的參考都是我看過的比較好的lldb的知識,大家瞭解可以通過我上面的一些網站,更加深入的第三篇,我一時半會不會寫的,因為那個才是真正的進階,而我還沒達到那種高度,如果你也有好的關於lldb的技巧,理解之類的,歡迎分享。