最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

深入理解 kernel panic 的流程

2023-06-26 16:26 作者:補(bǔ)給站Linux內(nèi)核  | 我要投稿

我們?cè)陧?xiàng)目開發(fā)過(guò)程中,很多時(shí)候會(huì)出現(xiàn)由于某種原因經(jīng)常會(huì)導(dǎo)致手機(jī)系統(tǒng)死機(jī)重啟的情況(重啟分Android重啟跟kernel重啟,而我們這里只討論kernel重啟也就是 kernel panic 的情況),死機(jī)重啟基本算是影響最嚴(yán)重的系統(tǒng)問(wèn)題了,有穩(wěn)定復(fù)現(xiàn)的,也有概率出現(xiàn)的,解題難度也千差萬(wàn)別,出現(xiàn)問(wèn)題后,通常我們會(huì)拿到類似這樣的kernel log信息(下面log僅以調(diào)用BUG()為例,其它異常所致的死機(jī)log信息會(huì)有一些不同之處):

這是linux 內(nèi)核在死機(jī)之前輸出的相關(guān)重要信息,包括PC指針、調(diào)用棧等在內(nèi)的非常重要的便于Debug的線索,比如我們可以借助GUN tools(add2Line)工具結(jié)合內(nèi)核符號(hào)映射表vmlinux來(lái)定位當(dāng)前PC指針?biāo)诘拇a具體行數(shù)(定位到出錯(cuò)代碼行并不意味著就找到了問(wèn)題的根本原因跟修復(fù)異常,這個(gè)需要根據(jù)異常的復(fù)雜程度而論)。深入理解這些關(guān)鍵打印log信息的含義和機(jī)制非常有助于我們對(duì)于此類死機(jī)問(wèn)題的定位和分析(對(duì)于內(nèi)存被踩、硬件不穩(wěn)定導(dǎo)致的一類問(wèn)題分析有局限性),這也是我們需要深入學(xué)習(xí)內(nèi)核異常流程的初衷。

這里我們必須弄清楚幾個(gè)問(wèn)題:

  • 這些死機(jī)前留下的關(guān)鍵register信息是怎么來(lái)的,有什么用,具體含義是什么?

  • 如何利用這些遺留的線索找到出問(wèn)題代碼具體在哪支文件,在哪一行?

  • 內(nèi)核發(fā)生致命異常到死機(jī)的總流程是怎樣的,類似死機(jī)問(wèn)題應(yīng)該如何著手分析?

為此,本文就從最常見的主動(dòng)觸發(fā)BUG()為例解析上面的疑問(wèn)及分析整個(gè)kernel panic流程。

什么是BUG() ?

有過(guò)驅(qū)動(dòng)調(diào)試經(jīng)驗(yàn)的人肯定都知道這個(gè)東西,這里的BUG跟我們一般認(rèn)為的“軟件缺陷”可不是一回事,這里說(shuō)的BUG()其實(shí)是linux kernel中用于攔截內(nèi)核程序超出預(yù)期的行為,屬于軟件主動(dòng)匯報(bào)異常的一種機(jī)制。這里有個(gè)疑問(wèn),就是什么時(shí)候會(huì)用到呢?一般來(lái)說(shuō)有兩種用到的情況,一是軟件開發(fā)過(guò)程中,若發(fā)現(xiàn)代碼邏輯出現(xiàn)致命fault后就可以調(diào)用BUG()讓kernel死掉(類似于assert),這樣方便于定位問(wèn)題,從而修正代碼執(zhí)行邏輯;另外一種情況就是,由于某種特殊原因(通常是為了debug而需抓ramdump),我們需要系統(tǒng)進(jìn)入kernel panic的情況下使用。

BUG()跟BUG_ON(1)其實(shí)本質(zhì)是一回事,后者只是在前者的基礎(chǔ)上做了簡(jiǎn)單的封裝而已,BUG()的實(shí)現(xiàn) 本質(zhì)是埋入一條未定義指令:0xe7f001f2,觸發(fā)ARM發(fā)起Undefined Instruction異常(PS:ARM有分10種異常類型,詳細(xì)可以復(fù)習(xí)ARM異常模型章節(jié))。

BUG() 流程分析

BUG()到系統(tǒng)重啟的總流程圖:

調(diào)用BUG()會(huì)向CPU下發(fā)一條未定義指令而觸發(fā)ARM發(fā)起未定義指令異常,隨后進(jìn)入kernel異常處理流程歷經(jīng) Oops,die(),__die()等流程輸出用于調(diào)試分析的關(guān)鍵線索,最后進(jìn)入panic()結(jié)束自己再獲得重生的過(guò)程,這個(gè)就是整個(gè)過(guò)程的基本流程,下面先來(lái)看die()具體做了什么呢?

die() 流程

源碼:

總流程大致如下:

通常來(lái)說(shuō),代碼分析過(guò)程結(jié)合kernel log一起看會(huì)理解來(lái)得更加深刻,如果是BUG()/BUG_ON(1)導(dǎo)致的異常,那么走到report_bug 就可以看到下面標(biāo)志性 log:

所以如果在log中看到了這個(gè) “[ cut here ]” 的信息就推斷是軟件發(fā)生致命fault而主動(dòng)call了BUG()所致的系統(tǒng)重啟了,就可以根據(jù)相關(guān)信息嘗試定位分析修復(fù)異常了.這里要注意的是還有另外一種__WARN()的情況也會(huì)打印出 “[ cut here ]” 的標(biāo)志性log但是內(nèi)核并不會(huì)掛掉,容易造成誤導(dǎo):

所以其實(shí)從顯現(xiàn)上很好區(qū)分兩種情況,如果是BUG()/BUG_ON(1)那么內(nèi)核一定會(huì)掛掉重啟,而__WARN()只會(huì)dump_stack()而不會(huì)死機(jī), 從源碼跟log信息也可以容易區(qū)分兩種情況,如果是BUG()/BUG_ON(1)的話一定有類似下面的log輸出,只要搜索關(guān)鍵字:“Internal error: Oops” 即可。


【文章福利】小編推薦自己的Linux內(nèi)核技術(shù)交流群:【749907784】整理了一些個(gè)人覺得比較好的學(xué)習(xí)書籍、視頻資料共享在群文件里面,有需要的可以自行添加哦?。。。ê曨l教程、電子書、實(shí)戰(zhàn)項(xiàng)目及代碼)? ? ??



__die() 流程分析

從上面輸出的log信息還不足以定位具體出問(wèn)題的代碼位置,包括定位異常所需要的最關(guān)鍵的 PC指針、調(diào)用棧等這些對(duì)于調(diào)試來(lái)說(shuō)至關(guān)重要的線索信息都是在__die()中輸出。

流程圖:

打印出標(biāo)志性log信息:

log 顯示異常str是Oops - BUG,error-code 為0,die計(jì)數(shù)器次數(shù):1

Oops 的本意為 “哎呀” 的一個(gè)俚語(yǔ),這里意形象的意指kernel出現(xiàn)了一件意外而不知道該如何處理的事件。

notify_die() 會(huì)通知對(duì)Oops感興趣的模塊執(zhí)行相關(guān)回調(diào),比如mtk的aee異常引擎模塊就是通過(guò)注冊(cè)到die_chain通知鏈上的。

mtk的aee異常引擎在kernel初始化的時(shí)候會(huì)去注冊(cè)到die_chain通知鏈,而且我們可以看到其實(shí)還注冊(cè)了panic通知鏈。

而對(duì)我們調(diào)試追蹤有用的關(guān)鍵信息是在 __show_regs() 里面打印的:

這里打印出了重要的pc停下的位置、相關(guān)寄存器信息,發(fā)生的是user還是kernel的異常、發(fā)生異常的cpu、進(jìn)程pid等信息。

接下來(lái) dump_mem() 用于dump出當(dāng)前線程的內(nèi)存信息:

使用 dump_backtrace(regs, tsk) 打印出調(diào)試最直觀的調(diào)用棧信息:

通過(guò)上面的調(diào)用棧信息結(jié)合GUN Tools(add2Line)基本就可以定位發(fā)生異常的具體代碼位置了。

最后會(huì)通過(guò)dump_instr(KERN_EMERG, regs) 打印出pc指針和前4條指令:

看到這個(gè) e7f001f2 了吧,是不是很眼熟?這個(gè)就是BUG()中埋入的未定義指令!

到這一步,大部分關(guān)鍵信息都已經(jīng)輸出了,可以通過(guò)add2Line工具定位出具體死在的代碼行號(hào),大致看看發(fā)生了什么,如果是BUG()導(dǎo)致的異常,那么就可以考慮分析和修復(fù)異常了,因?yàn)锽UG()屬于主動(dòng)匯報(bào)異常,一般來(lái)說(shuō)debug難度會(huì)相對(duì)其它的被動(dòng)上報(bào)方式容易得多.

例如:

從上面log知PC死在的地址,通過(guò)add2Line工具結(jié)合內(nèi)核符號(hào)映射表 vmlinux 就可以定位出具體代碼所在文件行號(hào):

定位到了具體代碼行號(hào)就可以進(jìn)一步分析代碼log找出問(wèn)題原因修復(fù)異常了(一般來(lái)說(shuō)BUG()導(dǎo)致的異常比較好解,其它的情況難度就是天差地別了..)。那么接下來(lái)kernel要干什么呢?重要信息都輸出完了接下來(lái)就直接走 kernel panic 流程了.

panic 流程

panic 本意是“恐慌”的意思,這里意旨kernel發(fā)生了致命錯(cuò)誤導(dǎo)致無(wú)法繼續(xù)運(yùn)行下去的情況。

流程圖:

最后附上總時(shí)序圖:


原文作者:人人極客社區(qū)



深入理解 kernel panic 的流程的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
凌海市| 屯门区| 镇巴县| 石首市| 仁布县| 施秉县| 吉林省| 天等县| 阳高县| 连南| 泗阳县| 玛纳斯县| 武平县| 营山县| 沧州市| 新巴尔虎左旗| 新田县| 百色市| 宜宾市| 白朗县| 布尔津县| 双桥区| 潢川县| 峡江县| 正蓝旗| 麻江县| 吉安县| 梨树县| 沈阳市| 岳普湖县| 阿瓦提县| 元阳县| 武义县| 霸州市| 图们市| 牙克石市| 西乌| 都江堰市| 泌阳县| 宣威市| 姜堰市|