關於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
- 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的使用
- 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命令
今天就先介紹到這裡,下一篇部落格我會介紹給大家如何使用開源的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
這裡大概會有30個命令吧,我記得我第一次裝的時候沒那麼多命令的,facebook又更新了很多。其實這些封裝的命令,就是使用python封裝了一下函式然後呼叫。凡是這些封裝的命令,你都可以通過多個lldb命令打出來,所以如果你會使用python的話,那麼你可以根據自己的使用習慣封裝一些常用的lldb命令。我使用了也有一段時間的chisel了,但是感覺並不是所有的命令都很常用,而且有寫使用的場景也不是很清楚,所以在這裡給大家普及一下,如果有謬誤,請大家及時指正。(ps:和大家說個快捷鍵,cmd+k快速清楚console的資訊。)
一般我們使用chisel的命令的時候,我們可以通過 help + chisel命令,譬如 help + pvc,得到如何具體使用這個命令,但是有時候你看了help資訊也不一定就會用呢。
image
pviews
這個命令是我最常使用的命令。它能夠幫助我們看到view的層級,即使我們並沒有觸發到一個斷點。操作如下:
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 0x79ec3140 -c green -w 2
border這個命令常常在我們需要檢視邊框的邊緣的問題,常常用到,而且我們想要設定的直接在lldb中設定,完全不需要重新寫程式碼再次執行。我就是通過直接暫停程式,並且通過pviews命令找到的控制元件的地址,並且呼叫命令顯示的。當我們不需要的時候可以通過unborder
這個命令去掉邊框。整個過程一氣呵成。
pinternals
pinternals
這個命令就是打印出來的一個控制元件(id
)型別的內部結構,詳細到令人髮指!甚至是你自定義的控制元件中的型別,譬如這個styleView
就是我自定義的,內部有個iconView的屬性,其中的值它也會打印出來。好處,你們自己琢磨吧。(ps:這個demo,我會在下一篇部落格中放出來,下篇部落格是說transform的。
presponder
打印出一個集成於UIResponder控制元件的訊息傳遞鏈。
presponder
這個也方便我們瞭解訊息是如何傳遞的,列印的時候是倒敘列印的。
visualize
可以使用mac下的預覽app開啟我們的圖片UIImage, CGImageRef格式的圖片,甚至view和layer的圖片 。
visualize 0x79ec3140//或者變數名,此地址是id型別的
pclass
pclass可以打印出一個物件的繼承關係。
pclass
taplog
這個命令是模擬敲擊一下螢幕,並且打印出你敲擊螢幕時候事件接收的物件。
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的方法是帶:
的。
其他命令
其它命令我用著並不是太多,並不代表他們不常用。只是我用的不太好而已,而且我認為用到是需要特殊的場景的,這個裡說幾個我感覺有很大作用但是我用的又不好的。
wivar
,這個命令是加watchPoint,用的好,就相當於使用lldb寫了kvo了。(ps:恕我沒研究明白)pvc
這個命令的作用是打印出當前的控制器層級,(ps:有時好使,有時又很壞,似魔鬼的步伐.?,沒研究明白)vs
,fv
,fvc
,這幾個命令都需要正則表示式的知識背景,因為我正則表示式從來都是百度,也沒自己真正學過。所以對我不常用,但是對那些會正則的可能會很大作用。(ps:希望你們研究出來有什麼好的技巧分享下)
參考
我寫的這些關於lldb的東西只是九牛一毛,它可以做的事情特別多,上面的參考都是我看過的比較好的lldb的知識,大家瞭解可以通過我上面的一些網站,更加深入的第三篇,我一時半會不會寫的,因為那個才是真正的進階,而我還沒達到那種高度,如果你也有好的關於lldb的技巧,理解之類的,歡迎分享。