調試程序-斷點,Debug,崩潰日誌分析,友盟崩潰日誌

一.設置和查看斷點
斷點可以分爲以下3種類型。
1. 文件行斷點設置
添加斷點->右鍵選擇Edit Breakpoint



Condition:指的是條件表達式,該項允許我們對斷點生效設置條件,表示當滿足某一特定條件的前提下,該斷點才生效。(該條件的錄入,不能夠識別預處理的宏定義,也不能識別斷點作用域之外的變量和方法)。eg:i == 1 ; (i == 1 || i == 2)

Ignore:忽略次數。它指定了在斷點生效,應用暫停之前,代碼忽略斷點的次數。你如果希望應用運行一段時間後斷點才生效,那麼就可以使用這個選項。比如說在調試某一循環體的時候。eg:Ignore 2 == 前兩次執行此處的代碼不會觸發該斷點,從第三次開始觸發該斷點。如果數字爲n,則從第n次開始觸發該斷點。

Action:動作。它表示當斷點生效時,Xcode作出反應後的行爲動作。點擊右邊的Add Action選項會彈出如圖

圖中所示紅色方框中的選項,可以讓你指定那一種動作。默認的是Debugger Command。還有以下幾種動作供選擇,下面逐一介紹。
它是蘋果提供的一種腳本語言,用來執行一些預先指定的行爲。選中該選項,將會出現如圖所示的AppleScript語言的輸入框。


大家可能看到了,我在輸入框中輸入了本門至高無上的心法祕訣,它的意思是彈出一個顯示“Hello World!”的對話框。點擊Compile按鈕後,如果沒有錯誤,會顯示成功信息。而點擊Test按鈕,會測試運行效果,如下圖


至於紅色方框中的內容是三種特殊符號相對應的定義。

符號標記 定義
@expression@ LLDB表達式
%B 斷點的名稱
%H 遇到該斷點的次數

(2).Capture GPU Frame
這個功能用於當斷點生效時,捕獲GPU當前所繪製的幀。該功能是輔助圖形調試的。

(3).Debugger Command
默認的選項,可以讓斷點執行LLDB調試命令。

po _imageArray 打印該斷點上面用到的數組內容

(4).Log Message
使用Log命令可以生成消息隊列,將相關的消息輸出到控制檯上,還有一個Speak Message選項,可以播報消息。


(5).Shell Command
該動作接收一個命令文件和參數列表。如下圖所示


命令文件必須是一個可執行的二進制程序或者腳本。可以複製粘貼輸入路徑,也可以點擊Choose按鈕選擇具體文件。
參數通過空格表示分割,也可以在兩個@字符之間包含LLDB表達式。
一般情況下,Xcode會異步執行Shell Command,也就是說,Shell Command 和調試器將會同步執行。如果希望調試器在Shell Command命令完成後運行,則可以勾選下面的Wait until done選項。

(6).Sound
動作會在斷點被觸發時,彈出聲音提示。



Options: 在執行完事件之後自動繼續執行。選中該選項之後,程序不會止步於該斷點,遇到該斷點也會繼續執行,但是會響應action中的調試信息。

2. 符號斷點設置
設置符號斷點與設置文件行斷點不同,需要點擊導航面板中的按鈕打開斷點導航面板,如圖15-10所示。
在斷點導航面板中,可以看到所有的斷點。


其中有兩項——Add Symbolic BreakpointAdd Exception Breakpoint,前者可以創建符號斷點,後者可以創建異常斷點。這裏我們選擇Add Symbolic Breakpoint菜單項,此時可以彈出創建符號斷點對話框,如圖


Symbol:後面可以是
1. 方法名稱:會對所有具有此方法名稱的類方法生效。例如 initWithFrame: 。 
2. 特定類的方法:OC類和C++類都適用,例如 ,[UIView initWithFrame:]或者 Shap::draw()。 
3. 函數名稱。例如普通C函數。

Module:是模組的意思,用來限制滿足符號的方法,編譯器將只會在斷點滿足這個模組的符號的時候纔回暫停

其餘的選項同上。

3. 異常斷點設置








Exception選項可以讓你選擇響應Objective-C對象拋出的異常,也可以選擇響應C++對象拋出的異常。
Break則是選擇斷點所接收的異常,是接收“Throw”語句拋出的異常還是Catch語句的。

3.OpenGL ES錯誤斷點(OpenGl ES Error Breakpoint)

這個斷點的作用和異常斷點類似,只不過這個斷點只有在openGL ES錯誤發生的時候纔會觸發。


4.測試失敗斷點 Test Failure Breakpoint

僅在測試斷點失敗的時候纔會執行,這個時候,應用將會暫停在引發測試失敗的代碼處,而不是停止在測試代碼處。

二、調試工具欄



模擬位置按鈕左邊的爲圖層查看按鈕,點擊可以查看界面的各個圖層

變量查看窗口

Auto。查看經常使用的變量。
Local Variables。查看本地變量。
Variables, Registers, Globals and Statics。查看全部變量,包括寄存器和全局變量等,如圖15-25所示,
其中圖標A是自動變量、S是靜態變量、R是寄存器、L是本地變量。

Print Description of “i”  打印變量信息
Edit Value…    編輯變量的值


三、日誌與斷言輸出
1.使用NSLog函數
2. 使用NSAssert宏
NSLog函數是無條件輸出,即程序運行到該語句,就會輸出結果。如果想有條件輸出結果,可以使用NSAssert
宏。注意,NSAssert並不是函數,它的定義如下:
#define NSAssert(condition, desc, ...)
其中第一個參數condition是布爾表達式,第二個參數desc是描述信息,參數後面的...是格式化desc描述信息
的。如果
conditionNO,則輸出desc描述信息,並拋出異常NSInternalInconsistencyException;如果
conditionYES,則不輸出信息。



2. 移除項目中的打印信息



(1)移除NSAssert




NS_BLOCK_ASSERTIONSFoundation框架中定義好的預處理宏,如果在編譯環境中設置NS_BLOCK_ASSERTIONS在編譯的時候NSAssert宏將被移
(2) 移除NSLog


擴展: 
1.自己在pch文件中預定義如下宏
#ifdef MY_MACRO
#define NAME @
"測試版本"
#else
#define NAME @
"上線版本"
#endif
2.
設置preprocessor Macros—>Debug(添加MY_MACRO=1)
3.在項目中使用NAME宏

如果項目Scheme編譯模式爲Debug  輸出:name = 測試版本
如果項目Scheme編譯模式爲release 輸出:name = 上線版本


四、LLDB調試工具
ppo就是調試工具的命令,調試工具的編譯器相對獨立於Xcode。我們進行Objective-C程序開發時,用過3種編譯器——GCCLLVM GCCApple LLVM,其中GCC是比較古老的編譯器,現在我們主要使用LLVM GCCApple LLVMGCC的調試工具是GDB,是GCC Debug工具的縮寫,LLVM GCCApple LLVM的調試工具是LLDB(或lldb進入LLDB調試工具的一種方式是從終端進入,另外一種是從Xcode進入。Xcode工具我們比較熟悉,這裏主要介紹這種方式。具體做法很簡單,就是在程序中設置斷點,當程序掛起時,在輸出窗口中選擇Debugger Output,這時輸出窗口有(lldb)
命令提示符,這就進入了LLDB調試工具了。
常用命令:po

五、異常堆棧報告分析





[exception reason] 異常產生的原因
[exception callStackSymbols] 符號化打印


查看設備的崩潰日誌


Window—>Devices—>View Device Logs

點擊Re-Symbolicate Log 符號化日誌信息
紅色標註部分指出崩潰代碼在ViewController0.m的第60行代碼

六、符號化設備的崩潰日誌
1.手動符號化設備的崩潰日誌

我們在ios開發中會碰到的很多crash問題,如果Debug調試模式的話,我們可以往往很容易的根據log的輸出定位到導致crash的原因,但對於已經上線的應用,或者是release環境包導致的crash,我們就需要一些特殊的手段來通過crash log進行分析定位了。

通過參考網上的一些資料,總結了一下,下面介紹一下通過dSYM文件以及crash log分析定位的方法。

1.導出crash log

通過Xcode的Organizer查看某臺iphone設備的DeviceLog,選擇需要的crash log,導出XXX.crash文件。

2.找到對應的app文件

找到當前iphone設備上安裝的ipa文件,更改文件後綴名爲zip,解壓後得到Payload文件夾,你需要的app文件就在其中了。

3.找到對應build版本的dSYM文件

dSYM文件是iOS編譯後保存16進制函數地址映射信息的文件,每次應用程序build後,都會生成對應的xxx.app, xxx.app.dSYM文件。






4.確定dSYM、app以及crash文件的關係

首先將dSYM、app以及crash放入同一個文件夾中,通過終端進入該文件夾。

每一個xx.app, xxx.app.dSYM文件都擁有相應的uuid,crash文件也有uuid,只有三者uuid一至才表明之三者可以解析出正確的日誌文件。
查看xx.app文件的uuid的方法,在terminal中輸入命令:

dwarfdump --uuid xxx.app/xxx (xxx工程名)

查看xx.app.dSYM文件的uuid的方法,在terminal中輸入命令:

dwarfdump --uuid xxx.app.dSYM (xxx工程名)

而.crash的uuid位於,crash日誌中的Binary Images:中的第一行尖括號內。如:

armv7 <8bdeaf1a0b233ac199728c2a0ebb4165>


5.通過symbolicatecrash分析crash文件

Xcode有自帶的symbolicatecrash工具,可以通過dSYM文件將crash文件中的16進制地址轉換成可讀的函數地址。該文件是隱藏文件,可以通過如下命令查找並拷貝到系統目錄下,並建立快捷方式。
1)打開終端,進入到symbolicatecrash工具所在的文件夾目錄
第一步:找到symbolicatecrash工具所在的文件夾目錄
find /Applications/Xcode.app -name symbolicatecrash(速度快)
或者
find /Applications/Xcode.app -name symbolicatecrash -type f
運行結果
/Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/symbolicatecrash

第二步:進入該目錄
cd /Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/symbolicatecrash

2)查找確認是否存在symbolicatecrash(可省略)
ls -al | grep symbolicatecrash

bogon:Resources bang$ ls -al | grep symbolicatecrash
-rwxr-xr-x   1 root  wheel    37893  2 26 10:22 symbolicatecrash

3)將symbolicatecrash工具拷貝到dSYM、app以及crash所在的文件夾
bogon:Crash bang$ cp symbolicatecrash /Users/bang/Desktop/Crash
4)執行如下命令,即可正確解析crash文件
./symbolicatecrash xxx.crash xxx.app.dSYM > test.txt
./symbolicatecrash DemoModel.crash CA3ACCD1-F63D-3A37-9773-82B155C02DA6.dSYM >crash2.txt

5)打開crash2.txt就可以看到符號化的崩潰日誌了



2.通過友盟符號化設備的崩潰日誌


如果出現bug的構建版本是在自己的電腦上打包的,那麼直接打開終端輸入黑色部分的代碼就能定位到崩潰的代碼位置;


如果出現bug的構建版本不是在自己電腦上打包的,那麼需要找到對應的構建版本拷貝到自己項目中構建版本的目錄中



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