值傳遞熏迹?址傳遞,慎用形參凝赛,崩潰修復(fù)記錄

查詢崩潰問題流程

  1. 拿到崩潰日志

  2. 查看崩潰線程注暗、崩潰原因

  3. 查看崩潰函數(shù)堆棧

  4. 確定崩潰調(diào)用參數(shù)

  5. 根據(jù)控制臺日志來具體分析問題

例子1:

  1. 拿到崩潰日志:
image.png
  1. 查看崩潰線程、崩潰原因
image.png

如圖墓猎,崩潰線程是線程5捆昏,崩潰類型是EXC_BREAKPOINT(SIGTRAP),下表是常見的崩潰異常,可以看到EXC_BREAKPOINT(SIGTRAP)是一種調(diào)試器相關(guān)的毙沾,跟蹤/斷點捕獲骗卜,多見于異常拋出。

UNIX 信號 注釋
SIGSEGV 訪問無效的內(nèi)存地址左胞。地址存在寇仓,但是應(yīng)用程序無法訪問。
SIGABRT 程序崩潰烤宙。由 C函數(shù) abort() 初始化遍烦。通常意味著系統(tǒng)檢測到某些事務(wù)出錯,例如 assert() 或者 NSAssert() 校驗失敗躺枕。
SIGBUS 訪問無效的內(nèi)存地址服猪。地址不存在,或?qū)R無效屯远。(The address does not exist, or the alignment is invalid.)
SIGTRAP 調(diào)試器相關(guān)
SIGILL 嘗試執(zhí)行非法的蔓姚、有缺陷、未知的或者需要權(quán)限的指令慨丐。
Mach 異常 描述 注釋
EXC_BAD_ACCESS 錯誤內(nèi)存訪問 訪問“錯誤”內(nèi)存地址⌒顾剑“錯誤”可能指“地址不存在”或者“應(yīng)用沒有權(quán)限訪問”房揭。因此通常與 SIGBUSSIGSEGV 相關(guān)聯(lián)备闲。
EXC_CRASH 異常跳出 通常與 SIGABRT 相關(guān)聯(lián),意思是由于檢測到代碼拋出的未捕獲異常而使應(yīng)用程序異常退出捅暴。
EXC_BREAKPOINT 跟蹤/斷點捕獲 通用與 SIGTRAP 相關(guān)聯(lián)恬砂。可以由你自己的代碼或者 NSExceptions 拋出時觸發(fā)蓬痒。
EXC_GUARD 違反了受保護資源的防護(Violated Guarded Resource Protection) 由違背受保護資源防護觸發(fā)泻骤,例如‘某些文件描述符’。
EXC_BAD_INSTRUCTION 非法指令 通常與特定非法或未定義指令/操作數(shù)相關(guān)梧奢。
EXC_RESOURCE 資源限制 應(yīng)用由于達到資源消耗限制而退出狱掂。
00000020 十六進制異常類型 非 'OS Kernel' 異常。
  1. 查看函數(shù)堆棧
image.png

如圖所示亲轨,我們最后崩潰在libobjc.A.dylib的objc_opt_respondsToSelector+48的地方趋惨,實際上,這是objc是否響應(yīng)selector的地方惦蚊,我們可以查看objc的源碼器虾,以下選自objc4-838

// Calls [obj respondsToSelector]
BOOL
objc_opt_respondsToSelector(id obj, SEL sel)
{
#if __OBJC2__
 if (slowpath(!obj)) return NO;
 Class cls = obj->getIsa();
 if (fastpath(!cls->hasCustomCore())) {
 return class_respondsToSelector_inst(obj, sel, cls);
 }
#endif
 return ((BOOL(*)(id, SEL, SEL))objc_msgSend)(obj, @selector(respondsToSelector:), sel);
}

為了弄清楚究竟崩在哪一行,我們需要把它轉(zhuǎn)成匯編

image.png

注意蹦锋,我們最后走到的是+48,這并不代表我們是執(zhí)行完+48所對應(yīng)的代碼才崩潰的兆沙,恰恰是執(zhí)行上一句代碼崩潰,而上一句代碼轉(zhuǎn)成匯編后的返回地址是+48莉掂,而上一句對應(yīng)的是

if (slowpath(!obj)) return NO;

也就是說此時objc不存在挤悉,結(jié)合前面的DDLog打印函數(shù),我們基本可以確定我們打印的對象已經(jīng)被釋放了巫湘,但是指針還沒有清空装悲,即指針?biāo)赶虻膬?nèi)存已釋放,而指針本身的地址不為null尚氛,所以它指向了一塊不可訪問的內(nèi)存诀诊。我們回到第5行,ResetVTSession阅嘶,來確定打印的是個啥

image.png
  1. 確定崩潰參數(shù)属瓣,還記得我們前面說的嗎,崩潰的偏移號不是代表我們執(zhí)行完這一句才崩潰讯柔,而是上一句抡蛙,之所以顯示+112偏移地址是因為上一句執(zhí)行完畢的返回地址是這個,可以很清楚的看到匯編其實已經(jīng)給我們注釋出來了魂迄,是"ResetVtSession = %@"調(diào)用出現(xiàn)的問題粗截,我們轉(zhuǎn)成正常代碼

    image-20220801151644486.png

現(xiàn)在我們確定了引發(fā)崩潰的參數(shù) vtSession.

  1. 現(xiàn)在我們來具體分析一下這個函數(shù)的究竟有什么問題,其實我們都不需要具體分析自己的日志就能看出來捣炬。
image.png

問題出在這里熊昌,vtSession = NULL绽榛,這是一句沒什么作用的代碼,反而很有迷惑性婿屹,為什么呢灭美?我們來分析一下這個方法想干什么,先強制編完剩下的幀VTCompressionSessionCompleteFrames,相當(dāng)于快速處理完還沒處理的內(nèi)容昂利,然后VTCompressionSessionInvalidate(vtSession)CFRelease(vtSession),這兩步是銷毀session届腐,并釋放內(nèi)存,最后再把vtSession置空蜂奸,看起來perfect犁苏,但是不要忘了我們的參數(shù)vtSession是值傳遞!換句話說我們在函數(shù)內(nèi)部的vtSession只是外部調(diào)用的值拷貝窝撵,就算我們把它置為空傀顾,也不影響外部的指針不為空,下次如果有其他線程重新調(diào)進來碌奉,就會引發(fā)崩潰短曾。所以解決方案有兩種,一是改為址傳遞赐劣,改為

void MHH264VideoSource::ResetVtSession(VTCompressionSessionRef& vtSession)

二是仍然是值傳遞嫉拐,不過外面手動把調(diào)用指針置空

// before:
     ResetVtSession(this->m_portrait_vtSession);
     ResetVtSession(this->m_landscape_vtSession);
// after:
    ResetVtSession(this->m_portrait_vtSession);
    this->m_portrait_vtSession = nullptr;
    ResetVtSession(this->m_landscape_vtSession);
    this->m_landscape_vtSession = nullptr;

總結(jié)

我們先通過崩潰日志確定崩潰類型和崩潰原因,然后根據(jù)崩潰堆棧來具體鎖定誘發(fā)崩潰的原因魁兼,然后再回到SDK層去查看具體引發(fā)崩潰的代碼和變量婉徘,最后我們再根據(jù)自己的代碼來具體排查為什么會這樣。

后話:雖然后來復(fù)盤的時候第5步我并沒有寫根據(jù)日志來排查咐汞,那是因為最后看了一圈日志最后又查回來到這個函數(shù)盖呼,發(fā)現(xiàn)是這里的問題,我一開始其實沒看出來這里的問題化撕,復(fù)盤的時候想寫簡單點几晤,畢竟業(yè)務(wù)上的設(shè)計各家各有不同,但是最基本的程序bug卻是類似的植阴。

后記

后面再分享一下我排查的具體操作吧蟹瘾,總體繞了一圈彎路

  1. 首先查看調(diào)用ResetVtSession的地方是ResetVtSession(this->m_landscape_vtSession)時崩潰,表明橫屏編碼器不存在掠手,但是豎屏編碼器能正常釋放

  2. 接著查看調(diào)用釋放的地方是verifyProcess(),這是一個嗅探機制憾朴,旨在查看當(dāng)前的碼流是否正常發(fā)送中,如果不正常喷鸽,就重新創(chuàng)建編碼器或刷新關(guān)鍵幀众雷,根據(jù)日志判斷,當(dāng)時檢測到豎屏碼流不能正常發(fā)送中,于是重新創(chuàng)建了一個豎屏的編碼器报腔,但是橫屏的沒有創(chuàng)建株搔,所以這一步可以得到一個信息:橫屏的編碼器壓根兒沒有(但是不能確定是已經(jīng)釋放了還是根本沒創(chuàng)建)

  3. 接著看上面的日志剖淀,發(fā)現(xiàn)走到了創(chuàng)建流程纯蛾,但是到加鎖創(chuàng)建的那一步,直接被return掉了纵隔,這里可以確定翻诉,vtSession并不為空,說明上一次釋放并沒有把指針置空

image-20220801154958737.png
  1. 接著就回到了上面捌刮,發(fā)現(xiàn)是釋放函數(shù)的問題碰煌。那么為什么之前一直沒出過問題呢?因為之前是啟動擴展進程绅作,每次都是新創(chuàng)建一個進程芦圾,所以everything is new,上一個擴展進程反正已經(jīng)沒了俄认,沒置空也不影響个少,所以一直沒啥問題,但是這一次咱們是用主進程采集流并發(fā)送的眯杏,導(dǎo)致整一個videoSource壓根兒已經(jīng)創(chuàng)建過就不用再創(chuàng)建了夜焦,所以這里vt_Session指針沒置空就很危險了,不光會導(dǎo)致下一次創(chuàng)建的時候創(chuàng)建不了岂贩,而且一旦走到析構(gòu)就直接咖喱給給了茫经。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市萎津,隨后出現(xiàn)的幾起案子卸伞,更是在濱河造成了極大的恐慌,老刑警劉巖锉屈,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件荤傲,死亡現(xiàn)場離奇詭異,居然都是意外死亡部念,警方通過查閱死者的電腦和手機弃酌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來儡炼,“玉大人妓湘,你說我怎么就攤上這事∥谘” “怎么了榜贴?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我唬党,道長鹃共,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任驶拱,我火速辦了婚禮霜浴,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蓝纲。我一直安慰自己阴孟,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布税迷。 她就那樣靜靜地躺著永丝,像睡著了一般。 火紅的嫁衣襯著肌膚如雪箭养。 梳的紋絲不亂的頭發(fā)上慕嚷,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天,我揣著相機與錄音毕泌,去河邊找鬼喝检。 笑死,一個胖子當(dāng)著我的面吹牛懈词,可吹牛的內(nèi)容都是我干的蛇耀。 我是一名探鬼主播,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼坎弯,長吁一口氣:“原來是場噩夢啊……” “哼纺涤!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起抠忘,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤撩炊,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后崎脉,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體拧咳,經(jīng)...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年囚灼,在試婚紗的時候發(fā)現(xiàn)自己被綠了骆膝。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,133評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡灶体,死狀恐怖阅签,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情蝎抽,我是刑警寧澤政钟,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響养交,放射性物質(zhì)發(fā)生泄漏精算。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一碎连、第九天 我趴在偏房一處隱蔽的房頂上張望灰羽。 院中可真熱鬧,春花似錦破花、人聲如沸谦趣。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至摘悴,卻和暖如春峭梳,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背蹂喻。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工葱椭, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人口四。 一個月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓孵运,卻偏偏與公主長得像,于是被迫代替她去往敵國和親蔓彩。 傳聞我的和親對象是個殘疾皇子治笨,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,077評論 2 355

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

  • 前言 此文是基于這些年工作中項目里面常見崩潰的一些總結(jié),整理出來方便查閱赤嚼,希望對大家都有所幫助旷赖。 App常見崩潰 ...
    Oneruofeng閱讀 16,887評論 3 21
  • [轉(zhuǎn)]HashMap和Hashtable的詳細區(qū)別[https://juejin.cn/post/68449039...
    Ella_Eric閱讀 288評論 0 2
  • 崩潰日志 如何得到crash report 當(dāng)一個iOS應(yīng)用程序崩潰時, 系統(tǒng)會創(chuàng)建一份crash日志保存在設(shè)備上...
    々莫等閑々閱讀 2,904評論 0 2
  • 1、前言 iOS 13 最大的亮點是 Dark 模式更卒,另一個就是蘋果登錄(Sign in with Apple)方...
    iHTCboy閱讀 40,314評論 25 19
  • iOS崩潰是讓iOS開發(fā)人員比較頭痛的事情等孵,app崩潰了,說明代碼寫的有問題蹂空,在這里了解一下XCode用來表示各種...
    Ly夢k閱讀 5,637評論 0 6