在項目的開發中,我們通常需要排查和修改測試中和發布后線上的一些bug,現在有一些第三方的bug分享和查找工具SDK,如騰訊的Bugly和聽雲等,包括蘋果的開發工具xcode也自帶 bug查找工具。那么這些工具又是如何獲取到程序中的bug日志的?這里就要談到DSYM文件了,一個很重要的東西。
什么是DSYM文件?——DSYM是符號表文件
那什么是符號表了?——符號表是內存地址與函數名、文件名、行號的映射表。符號表元素如下所示:<起始地址> <結束地址> <函數> [<文件名:行號>]
類似於android構建release包時的mapping文件,我們利用mapping文件可以將混淆后的APP運行時的現成堆棧信息還原成混淆前的堆棧信息(利用retrace 工具)。所以當應用crash時,我們可以利用crash時的堆棧信息得到對應到源代碼的堆棧信息,還能看到出錯的代碼在多少行,所以能快速定位出錯的代碼位置,以便快速解決問題。而iOS應用crash時也有堆棧,release版的應用,crash時的堆棧信息,全是二進制的地址信息。如果利用這些二進制的地址信息來定位問題是不可能的,因此我們需要將這些二進制的地址信息還原成源代碼中的函數以及行號,這時候就需要符號表了。舉個例子如下圖
Xcode編譯項目后,我們會看到一個同名的 dSYM 文件,dSYM 是保存 16 進制函數地址映射信息的中轉文件,我們調試的 symbols 都會包含在這個文件中,並且每次編譯項目的時候都會生成一個新的 dSYM 文件,位於 /Users/<用戶名>/Library/Developer/Xcode/Archives 目錄下。iOS 設備中會有日志文件保存我們每個應用出錯的函數內存地址,通過 Xcode 的 Organizer 可以將 iOS 設備中的 DeviceLog 導出成 crash 文件,這個時候我們就可以通過出錯的函數地址去查詢 dSYM 文件中程序對應的函數名和文件名。
如何將文件一一對應
每一個 xx.app 和 xx.app.dSYM 文件都有對應的 UUID,crash 文件也有自己的 UUID,只要這三個文件的 UUID 一致,我們就可以通過他們解析出正確的錯誤函數信息了。
1.查看 xx.app 文件的 UUID,terminal 中輸入命令 :dwarfdump --uuid xx.app/xx (xx代表你的項目名)
2.查看 xx.app.dSYM 文件的 UUID ,在 terminal 中輸入命令:dwarfdump --uuid xx.app.dSYM
3.crash 文件內第一行 Incident Identifier 就是該 crash 文件的 UUID。
在騰訊bugly和聽雲中都實現了符號表自動上傳功能,可以直接在管理后台查看到bug報錯的具體位置。原理也是把DSYM文件上傳到他們自己的服務器。
例如聽雲的實現方式如下:
在Xcode工程對應Target的Build Phases
中新增Run Scrpit Phase
使用Xcode 自帶的Crashes工具也能查找bug位置,這個是能查找release線上版本的,debug的無法查找。
iOS—lj