關(guān)于符號(hào)化(symbolic)和奔潰信息的分析

最初始的需求是:怎么定位線上的奔潰。

那就是捕獲NSException创橄,收集發(fā)送到后臺(tái)統(tǒng)一處理弟翘〕嬉福或者接入第三方奔潰統(tǒng)計(jì)的庫(kù),讓他們把這些都做了稀余。

這里面都有一個(gè)繞不過(guò)的問(wèn)題是悦冀,得到的信息里有些是未符號(hào)化、顯示為內(nèi)存地址的信息:


是否符號(hào)化區(qū)別.png

怎么把地址轉(zhuǎn)為對(duì)應(yīng)的方法/函數(shù)就是符號(hào)化的任務(wù)睛琳。為啥叫符號(hào)化盒蟆?在編譯鏈接系統(tǒng)中,函數(shù)师骗、變量這些都被認(rèn)為是符號(hào)历等,有一個(gè)叫符號(hào)表的東西:

在符號(hào)表中,程序源代碼中的每個(gè)標(biāo)識(shí)符都和它的聲明或使用信息綁定在一起辟癌,比如其數(shù)據(jù)類型寒屯、作用域以及內(nèi)存地址

所以解析過(guò)程需要的材料就是符號(hào)表黍少,用它就可以用地址反向定位它的符號(hào)寡夹,得到需要的方法名。

  • 對(duì)于我們的APP厂置,符號(hào)表就在dSYMs文件里菩掏,dSYMs應(yīng)該就是debug symbols的縮寫。
  • 對(duì)于系統(tǒng)庫(kù)昵济,如UIKit智绸,在它們的framework里野揪。/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/System/Library/Frameworks/UIKit.framework

奔潰信息的獲取

  • 手機(jī)直接導(dǎo)入:window --> device --> view device logs. 這里面是格式化的crash文件,而且用Xcode查看時(shí)會(huì)自動(dòng)符號(hào)化传于。
  • 在App Store上查看囱挑,這個(gè)需要用戶在設(shè)置里同意了上傳奔潰信息。
  • 前面兩種幾乎沒(méi)什么暖用沼溜,對(duì)于線上的奔潰信息平挑,得自己獲取:
//沒(méi)有捕獲的異常會(huì)調(diào)用這里設(shè)置的函數(shù)
NSSetUncaughtExceptionHandler(analyzeAndSaveException);

void analyzeAndSaveException(NSException *exception){
    NSArray<NSString *> *symbols = [exception callStackSymbols];
    NSString *reason = [exception reason];
    NSDictionary *userInfo = [exception userInfo];
    NSString *name = [exception name];
    
    //按某種格式存到本地系草,然后上傳到服務(wù)器
}

測(cè)試了下通熄,在這個(gè)函數(shù)執(zhí)行結(jié)束前,程序是不會(huì)狗帶的找都,網(wǎng)絡(luò)請(qǐng)求這種需要等待回調(diào)的肯定是不行了唇辨,但寫到本地文件里還是可以的。

重點(diǎn)就是這個(gè)callStackSymbols能耻,是引起奔潰的函數(shù)的調(diào)用棧赏枚,比如:

奔潰調(diào)用棧

這里就是部分符號(hào)化的,4-17這些都是顯示的內(nèi)存地址晓猛。如果是打包后安裝的APP饿幅,調(diào)用棧跟上面直接連接xcode運(yùn)行的又不同,關(guān)鍵性的第三點(diǎn)是這樣的:
"3 CrashAnalyze 0x00000001000dbda8 CrashAnalyze + 32168"

符號(hào)化命令

atos -arch <Binary Architecture> -o <Path to dSYM file>/Contents/Resources/DWARF/<binary image name> -l <load address> <address to symbolicate>

  • -arch 指定對(duì)應(yīng)的cpu架構(gòu)
  • -o 指定符號(hào)表路徑戒职,對(duì)APP本身的方法是dSYM文件路徑/Contents/Resources/DWARF/app名稱,對(duì)系統(tǒng)方法是/Users/shiwei/Library/Developer/Xcode/iOS\ DeviceSupport/10.3.3\ \(14G60\)/Symbols/System/Library/Frameworks/庫(kù)名.framework/庫(kù)名栗恩,注意路徑有個(gè)版本區(qū)別。
  • -l 指定load address,就是這個(gè)庫(kù)加載的地址
  • 最后的是需要被符號(hào)化的地址

從命令里可以看出洪燥,奔潰日志需要這些信息:

  • 機(jī)型磕秤,有了這個(gè)就知道cpu架構(gòu)了
  • 系統(tǒng)版本,有系統(tǒng)版本可以知道對(duì)應(yīng)的系統(tǒng)庫(kù)的版本捧韵,但最好是每個(gè)庫(kù)的UUID市咆,ID總是不會(huì)錯(cuò)的。
  • 每個(gè)庫(kù)的加載地址纫版。

以前也有一些符號(hào)化和dSYMs文件的文章和工具床绪,我試了下,好像沒(méi)用了其弊。區(qū)別是沒(méi)有考慮load address的問(wèn)題癞己,具體的我沒(méi)仔細(xì)考證。

怎么知道是哪個(gè)庫(kù)的方法梭伐?

  • 調(diào)用棧里的每條前面都有庫(kù)的名字痹雅,自己APP的代碼就是APP的名稱
  • 我觀察到一點(diǎn):加載地址是有區(qū)間的,比如加載地址從小到大是:libA --- libB --- libC,而需要符號(hào)化的地址落在libB和libC之間糊识,那么就是libB的函數(shù)了绩社。

怎么獲取加載地址摔蓝?

#import <mach-o/dyld.h>
.....
uint32_t numImages = _dyld_image_count();
    for (uint32_t i = 0; i < numImages; i++) {
        const struct mach_header *header = _dyld_get_image_header(i);
        const char *name = _dyld_get_image_name(i);
        const char *p = strrchr(name, '/');
        if (p) {
             NSLog(@"module=%s, address=%p", p + 1, header);
        }
    }

怎么獲取UUID?
iOS 如何獲取 Mach-O 的 UUID

測(cè)試:

//對(duì)APP本身
atos -arch arm64 -o ~/Desktop/CrashAnalyze.app.dSYM/Contents/Resources/DWARF/CrashAnalyze -l 0x100068000 0x10006fd8c

-[ViewController triggerException] (in CrashAnalyze) (ViewController.m:61)

//對(duì)UIKit
atos -arch arm64 -o /Users/shiwei/Library/Developer/Xcode/iOS\ DeviceSupport/10.3.3\ \(14G60\)/Symbols/System/Library/Frameworks/UIKit.framework/UIKit -l 0x196f2d000 0x0000000196f71bd4

-[UIControl sendAction:to:forEvent:] (in UIKit) + 80

系統(tǒng)庫(kù)的符號(hào)化更多看這里

最后

這些東西如果要自己手動(dòng)處理確實(shí)很麻煩,因?yàn)楸匾臄?shù)據(jù)和材料都可以上傳給服務(wù)器愉耙,所以做一套系統(tǒng)贮尉,自動(dòng)上報(bào)crash信息,后臺(tái)根據(jù)提供的符號(hào)表或dSYMs文件朴沿,再加上各個(gè)系統(tǒng)庫(kù)的各個(gè)版本的符號(hào)表猜谚,就可以讓程序自動(dòng)去處理這些。

這樣一個(gè)自動(dòng)化的系統(tǒng)才更有價(jià)值吧赌渣!

然后看了下Bugly做了這樣的處理魏铅,Bugly iOS 符號(hào)表配置

Understanding and Analyzing Application Crash Reports
iOS Crash分析必備:符號(hào)化系統(tǒng)庫(kù)方法
符號(hào)表

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市坚芜,隨后出現(xiàn)的幾起案子览芳,更是在濱河造成了極大的恐慌,老刑警劉巖鸿竖,帶你破解...
    沈念sama閱讀 218,284評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件沧竟,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡缚忧,警方通過(guò)查閱死者的電腦和手機(jī)屯仗,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)搔谴,“玉大人,你說(shuō)我怎么就攤上這事桩撮《氐冢” “怎么了?”我有些...
    開封第一講書人閱讀 164,614評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵店量,是天一觀的道長(zhǎng)芜果。 經(jīng)常有香客問(wèn)我,道長(zhǎng)融师,這世上最難降的妖魔是什么右钾? 我笑而不...
    開封第一講書人閱讀 58,671評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮旱爆,結(jié)果婚禮上舀射,老公的妹妹穿的比我還像新娘。我一直安慰自己怀伦,他們只是感情好脆烟,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,699評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著房待,像睡著了一般邢羔。 火紅的嫁衣襯著肌膚如雪驼抹。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,562評(píng)論 1 305
  • 那天拜鹤,我揣著相機(jī)與錄音框冀,去河邊找鬼。 笑死敏簿,一個(gè)胖子當(dāng)著我的面吹牛明也,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播极谊,決...
    沈念sama閱讀 40,309評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼诡右,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了轻猖?” 一聲冷哼從身側(cè)響起帆吻,我...
    開封第一講書人閱讀 39,223評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎咙边,沒(méi)想到半個(gè)月后猜煮,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,668評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡败许,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,859評(píng)論 3 336
  • 正文 我和宋清朗相戀三年王带,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片市殷。...
    茶點(diǎn)故事閱讀 39,981評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡愕撰,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出醋寝,到底是詐尸還是另有隱情搞挣,我是刑警寧澤,帶...
    沈念sama閱讀 35,705評(píng)論 5 347
  • 正文 年R本政府宣布音羞,位于F島的核電站囱桨,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏嗅绰。R本人自食惡果不足惜舍肠,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,310評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望窘面。 院中可真熱鬧翠语,春花似錦、人聲如沸财边。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)制圈。三九已至们童,卻和暖如春畔况,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背慧库。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工跷跪, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人齐板。 一個(gè)月前我還...
    沈念sama閱讀 48,146評(píng)論 3 370
  • 正文 我出身青樓吵瞻,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親甘磨。 傳聞我的和親對(duì)象是個(gè)殘疾皇子橡羞,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,933評(píng)論 2 355

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