iOS崩潰堆棧信息的符號化解析

最近一段時間肩袍,在iOS開發(fā)調(diào)試過程中以及上線之后,程序經(jīng)常會出現(xiàn)崩潰的問題婚惫。簡單的崩潰還好說氛赐,復雜的崩潰就需要我們通過解析Crash文件來分析了,解析Crash文件在iOS開發(fā)中是比較常見的先舷。但在跟開發(fā)者溝通過程中艰管,云捕小編發(fā)覺大家對iOS的應用符號表還不是很清楚。

現(xiàn)在網(wǎng)上有很多關于解析崩潰堆棧信息的符號化的博客蒋川,但是大多質(zhì)量參差不齊牲芋,或者有些細節(jié)沒有注意到。今天總結(jié)一下對iOS崩潰符號化的使用和技巧:

一.場景

當我們收集iOS的崩潰信息時捺球,獲取到的崩潰堆棧一般是如下的形式缸浦,全是十六進制的內(nèi)存地址形式:

這樣的格式我們很難看出實際含義,無法定位問題代碼氮兵,只有將它們轉(zhuǎn)化為可讀的形式才有意義:

如上所示裂逐,我們一眼就能看明白,這次崩潰發(fā)生在ViewController.m文件的68行泣栈,對應的方法是rangeException絮姆。那么這樣的符號化又是如何實現(xiàn)的呢醉冤?

我們知道,開發(fā)者在使用Xcode開發(fā)調(diào)試App時篙悯,一旦遇到崩潰問題蚁阳,開發(fā)者可以直接使用Xcode的調(diào)試器定位分析崩潰堆棧。但如果App發(fā)布上線鸽照,用戶的手機發(fā)生了崩潰螺捐,我們就只能通過分析系統(tǒng)記錄的崩潰日志來定位問題,在這份崩潰日志文件中矮燎,會指出App出錯的函數(shù)內(nèi)存地址定血,關鍵的問題,崩潰日志中只有地址诞外,類似 0x2312e92f這種澜沟,這看起來豈不是相當頭疼,那怎么辦呢峡谊?

幸好有dSYM文件的存在茫虽,它是幫助苦逼的碼農(nóng)有效定位bug問題的重要途徑。崩潰堆棧里的函數(shù)地址可以借助dSYM文件來找到具體的文件名既们、函數(shù)名和行號信息的濒析。實際上,在使用Xcode的Organizer查看崩潰日志時啥纸,就是根據(jù)本地存儲的.dSYM文件進行了符號化的操作号杏。

二.Xcode符號化工具

Xcode本身也提供了幾個工具來幫助開發(fā)者執(zhí)行函數(shù)地址符號化的操作

1、symbolicatecrash

symbolicatecrash是一個將堆棧地址符號化的腳本斯棒,輸入?yún)?shù)是蘋果官方格式的崩潰日志及本地的.dSYM文件盾致,

執(zhí)行方式如下:

Symbolicatecrash + 崩潰日志 + APP對應的.dSYM文件 + > + 輸出到的文件,

但使用symbolicatecrash工具有很大的限制

(1)只能分析官方格式的崩潰日志荣暮,需要從具體的設備中導出绰上,獲取和操作都不是很方便

(2)符號化的結(jié)果也是沒有具體的行號信息的,也經(jīng)常會出現(xiàn)符號化失敗的情況渠驼。

實際上, Xcode的Organizer內(nèi)置了symbolicatecrash工具,所以開發(fā)者才可以直接看到符號化的崩潰堆棧日志鉴腻。

2迷扇、atos

更普遍的情況是,開發(fā)者能獲取到錯誤堆棧信息爽哎,而使用atos工具就是把地址對應的具體符號信息找到蜓席。它是一個可以把地址轉(zhuǎn)換為函數(shù)名(包括行號)的工具,

執(zhí)行方式如下:

atos -o executable -arch architecture -l loadAddress address

說明:

loadAddress 表示函數(shù)的動態(tài)加載地址课锌,對應崩潰地址堆棧中 + 號前面的地址厨内,即0x00048000

address 表示運行時地址祈秕、對應崩潰地址堆棧中第一個地址,即0x0004fbed? 雏胃,實際上请毛,崩潰地址堆棧中+號前后的地址相加即是運行時地址,即0x00048000+ 31720= 0x0004fbed

執(zhí)行命令查詢地址的符號瞭亮,可以看到如下結(jié)果:

-[ViewController rangeException:] (in xx)(ViewController.m:68)

三.堆棧符號化原理

那么方仿,如果我們自己來符號化堆棧,又該怎么實現(xiàn)呢统翩?這里需要處理兩種符號仙蚜,包括用戶符號和系統(tǒng)符號。

1厂汗、用戶堆棧的符號化

符號化的依據(jù)來自dSYM文件委粉, dSYM文件也是Mach-o格式,我們按照Mach-o格式一步一步解析即可娶桦。

從圖上我們可以大概的看出Mach-O可以分為3個部分

(1)Header

(2)Segment

(3)section

如圖所示贾节,header后面是segment,然后再跟著section趟紊,而一個segment是可以包含多個section的氮双。

我們把dSYM文件放入可視化工具:

該dSYM文件包含armv7和arm64兩種架構(gòu)的符號表,我們只看armv7(arm64同理)霎匈,它偏移64戴差,直接定位到64(0x00000040),這里就是上面的Mach Header信息

跟我們符號表有關的兩個地方,一是”LC_SYMTAB”, 二是“LC_SEGMENT(__DWARF)” -> “Section Header(__debug_line)”铛嘱。

LC_SYMTAB信息

定位地址: 偏移4096 + 64(0x1040),得到函數(shù)符號信息模塊”Symbols”,把函數(shù)符號解析出來暖释,比如第一個函數(shù): “-[DKDLicenseAgreeementModel isAuthorize]”對應的內(nèi)存地址:模塊地址+43856

“__debug_line”模塊

這個模塊里包含有代碼文件行號信息,根據(jù)dwarf格式去一個一個解析

首先定位到SEGMENT:LC_SEGMENT(__DWARF)墨吓,再定位到Section:__debug_line

它的偏移值:4248608,? 4248608+ 64 = 0x40D460球匕,定位到“Section(__DWARF,__debug_line)”

這里面就是具體的行號信息,根據(jù)dwarf格式去解析

解析出來的結(jié)果如下:

第一列是起始內(nèi)存地址帖烘,第二列是結(jié)束內(nèi)存地址亮曹,第三列是對應的函數(shù)名、文件名秘症、行號信息照卦,這樣我們捕獲到任意的崩潰信息后,都可以很輕松的還原了乡摹。

上面解析出來的Object-C符號倒沒什么問題役耕,但如果是C++或者Swift的符號就還需要特殊處理

Swift符號:

Swift函數(shù)會進行命名重整(name mangling),所以從dSYM中解析出來的原始符號是不太直觀的

我們使用”swift-demangle”來還原:swift-demangle –simplified originName,結(jié)果如下:

C++符號:

C++函數(shù)也會進行命名重整(name mangling),所以從dSYM中解析出來的原始符號如下:

我們使用”c++filt ”來還原: c++filt originName聪廉,結(jié)果如下:

2瞬痘、系統(tǒng)堆棧的符號化

未解析形式:

解析后:

Apple沒有提供系統(tǒng)庫符號表的下載功能故慈,我們可以通過真機來獲取

當把開發(fā)機連到MAC時,會首先把該機型的符號拷貝到電腦上框全。

“Processing symbol files”做的事情就是把系統(tǒng)符號拷貝到電腦察绷,拷貝地址:

~/Library/Developer/Xcode/iOS DeviceSupport

但這樣有個缺陷,那就是你真機的iOS版本不會足夠多竣况,包含所有版本克婶,所以系統(tǒng)符號會有缺失,另一個辦法就是下載各種iOS固件丹泉,從固件中去解析情萤。

四.結(jié)語

在實際的項目開發(fā)中,崩潰問題的分析定位都不是采用這種方式摹恨,因為它依賴于系統(tǒng)記錄的崩潰日志或錯誤堆棧筋岛,在本地開發(fā)調(diào)試階段,是沒有問題的晒哄。

如果在發(fā)布的線上版本出現(xiàn)崩潰問題睁宰,開發(fā)者是無法即時準確的取得錯誤堆棧。一般地寝凌,開發(fā)者都是接入第三方的崩潰監(jiān)控服務(如網(wǎng)易云捕)柒傻,實現(xiàn)線上版本崩潰問題的記錄和跟蹤。

網(wǎng)易云捕-網(wǎng)易旗下最專業(yè)的APP質(zhì)量跟蹤平臺

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末较木,一起剝皮案震驚了整個濱河市红符,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌伐债,老刑警劉巖预侯,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異峰锁,居然都是意外死亡萎馅,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進店門虹蒋,熙熙樓的掌柜王于貴愁眉苦臉地迎上來糜芳,“玉大人,你說我怎么就攤上這事魄衅∏涂ⅲ” “怎么了?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵徐绑,是天一觀的道長。 經(jīng)常有香客問我莫辨,道長傲茄,這世上最難降的妖魔是什么毅访? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮盘榨,結(jié)果婚禮上喻粹,老公的妹妹穿的比我還像新娘。我一直安慰自己草巡,他們只是感情好守呜,可當我...
    茶點故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著山憨,像睡著了一般查乒。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上郁竟,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天玛迄,我揣著相機與錄音,去河邊找鬼棚亩。 笑死蓖议,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的讥蟆。 我是一名探鬼主播勒虾,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼瘸彤!你這毒婦竟也來了修然?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤钧栖,失蹤者是張志新(化名)和其女友劉穎低零,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體拯杠,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡掏婶,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了潭陪。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片雄妥。...
    茶點故事閱讀 39,696評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖依溯,靈堂內(nèi)的尸體忽然破棺而出老厌,到底是詐尸還是另有隱情,我是刑警寧澤黎炉,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布枝秤,位于F島的核電站,受9級特大地震影響慷嗜,放射性物質(zhì)發(fā)生泄漏淀弹。R本人自食惡果不足惜丹壕,卻給世界環(huán)境...
    茶點故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望薇溃。 院中可真熱鬧菌赖,春花似錦、人聲如沸沐序。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽策幼。三九已至邑时,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間垄惧,已是汗流浹背刁愿。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留到逊,地道東北人铣口。 一個月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像觉壶,于是被迫代替她去往敵國和親脑题。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,592評論 2 353

推薦閱讀更多精彩內(nèi)容

  • 該文章屬于劉小壯原創(chuàng)铜靶,轉(zhuǎn)載請注明:劉小壯[http://www.reibang.com/u/2de707c93d...
    劉小壯閱讀 37,563評論 45 122
  • 前言 iOS崩潰是讓iOS開發(fā)人員比較頭痛的事情叔遂,app崩潰了,說明代碼寫的有問題争剿,這時如何快速定位到崩潰的地方很...
    齊滇大圣閱讀 65,318評論 29 443
  • 前言 崩潰是讓發(fā)人員比較頭痛的事情已艰,app崩潰了,說明代碼寫的有問題蚕苇,這時如何快速定位到崩潰的地方很重要哩掺。調(diào)試階段...
    進無盡閱讀 2,017評論 0 9
  • 前言 作為一個程序開發(fā)人員,調(diào)試程序編寫過程中遇到的各種異常奔潰涩笤,是再常見不過的現(xiàn)象了嚼吞。一般在開發(fā)過程中,我們可以...
    brilliance_Liu閱讀 1,776評論 7 6
  • 前天蹬碧,我在朋友圈發(fā)了偶像演唱會的照片舱禽,有朋友說“我真想屏蔽你!” 今天恩沽,和朋友一起吃飯誊稚,朋友說“你別追星了,趕緊找...
    花小茂閱讀 664評論 0 0