Kernel Panic常見原因以及解決方法


Technorati 標簽: Kernel Panic

出現原因

1. Linux在中斷處理程序中,它不處於任何一個進程上下文,如果使用可能睡眠的函數,則系統調度會被破壞,導致kernel panic。因此,在中斷處理程序中,是不能使用有可能導致睡眠的函數(例如信號量等)。

在中斷發起的軟中斷中,其上下文環境有可能是中斷上下文,同理,也不能調用可能導致睡眠的函數。軟中斷執行時,全局中斷是打開的,而中斷程序執行時,全局中斷是禁止的。

軟中斷除了系統調度進入點,當軟中斷數量頻繁時,內核中有一個專門的軟中斷的后台程序daemon來處理其事務。

 

2. 內核堆棧溢出,或者指針異常訪問時,會出現kernel panic。

    堆棧溢出:程序循環或者多層嵌套的深度過多時,可能會導致棧溢出。參考Linux的內存模型

 

3. 除0異常、內存訪問越界、緩沖區溢出等錯誤時,當這些事件發生在應用程序時,Linux內核的異常處理機制可以對這些由應用程序引起的情況予以處理。當應用程序出現不可恢復性錯誤時,Linux內核可以僅僅終止產生錯誤的應用程序,而不影響其他程序。

  如果上述操作發生在內核空間,就會引起kernel panic。

4. 內核陷入死鎖狀態,自旋鎖有嵌套使用的情況。

5. 在內核線程中,存在死循環的操作。

 

解決方法

1. 全部排查內核中可能造成睡眠的函數調用地方。如果是自己寫的模塊,則在調用睡眠函數之前打印出特征日志,以備查驗。

     在內核代碼中的特定位置加入printk調試調用,直接把需要關心的信息打印到屏幕上,從而得知程序執行的路徑。

2. 在可疑的地方,調用dump_stack()函數或者__backtrace(),打印當前CPU的堆棧調用函數。

3. 打開Linux內核的崩潰轉儲機制(kdump機制,生產vmcore文件),當系統crash時,將內存內容保存到磁盤,或者通過網絡發送到故障服務器,或者直接使用內核調試器。crash工具用於調試內核崩潰轉儲文件。

詳細測試方法:Crash工具實戰-變量解析

5. 使用內核自帶的 notify_chain機制。Linux內核提供“通知鏈”功能,並預定義了一個內核崩潰通知鏈。當kernel panic時,異常處理程序會沿着預定義的通知鏈順序調用注冊到通知鏈中的通知函數。

6. 在RedHat、StackOverflow、查找出現bug的歷史解決方案,

7. 調試方法,采用kprobe來調試內核。Kprobe在Linux kernel debug中的應用

8. 對於一些未定義指令的錯誤,在出現的錯誤log中 ,Oops - undefined instruction: 0 [#1] PREEMPT SMP ARM,結合原始鏡像的system.map文件,來定位。參考鏈接:Linux kernel crash analysis

9. systemtap調試工具

10. gcore工具

 

-------------------------------2014-08-08分界線------------------------------------------------

在學習Linux中,從《LInux內核設計與實現》里面,看到一本《Linux 內核精髓:精通Linux內核必會的75個絕技》,這本書是日本人高橋浩和寫的,在書籍的合住作者,大岩尚宏,他編寫了《Debug Hack》一書,這本是有關Linux內核調試的書籍,大喜。真是按圖索驥,逐漸發現新的寶貝書籍。

 

內核調試工具介紹以及使用

    Kdb

  kdb是Linux內核的補丁,提供了一種在系統運行時,對內核內存和數據結構進行檢查的方法,不是源碼級別的調試工具。kdb主要目標在於開發和診斷一些內核的問題。

  打開KALLSYMS:General setup-->Configure standard kernel features-->Load all symblos for debugging/ksymoops

  開啟kdb服務

 

     Kprobe

     kprobe(內核探測,kernel probe)是一個動態地收集調試和性能信息的工具,如:收集寄存器和全局數據結構等調試信息,無需對Linux內核頻繁編譯和啟動。用戶可以在任何內核代碼地址進行陷阱,指定調試斷點觸發時的處理例程。工作機制是:用戶指定一個探測點,並把用戶定義的處理函數關聯到該探測點,當內核執行到該探測點時,相應的關聯函數被執行,然后繼續執行正常的代碼路徑。

 

     Kprobes 提供了一個強行進入任何內核例程並從中斷處理器無干擾地收集信息的接口

    Kprobes 向運行的內核中給定地址寫入斷點指令,插入一個探測器。執行被探測的指令會導致斷點錯誤。Kprobes 鈎住(hook in)斷點處理器並收集調試信息。Kprobes 甚至可以單步執行被探測的指令。

內核探測分為kprobe, jprobe和kretprobe(也稱return probe,返回探測)三種。

kprobe可插入內核中任何指令處;

jprobe插入內核函數入口,方便於訪問函數的參數;

return probe用於探測指定函數的返回值。

內核配置

CONFIG_KPROBES                  General Setup--->Kprobe

CONFIG_MODULES                  √             

CONFIG_MODULE_UNLOAD   √

CONFIG_KALLSYMS_ALL                   General Setup--->Configure standard kernel configuration-->Include all symbols in kallsyms

CONFIG_KALLSYMS                           General Setup--->Configure standard kernel configuration-->Load all symbols for debugging/ksymoops

CONFIG_KALLSYMS_EXTRA_PASS    General setup-->Configure standard kernel features-->Load all symbols for debugging/ksymoops

CONFIG_DEBUG_INFO                       Kernel hacking-->Kernel debugging-->Compile the kernel with debug info

CONFIG_DEBUG_FS                           Kernel hacking-->Debug Filesystem

讓內核支持DEBUGFS,使能宏CONFIG_DEBUG_FS

CONFIG_RELAY: General Setup -> user spacerelay support

編譯通過,不過生成的鏡像文件太大,要精簡。

去掉I2C和MMC卡驅動的支持,

PPP網絡支持,       Device  Drivers--->Netowork device supprot-->PPP protocol

去掉WiFI的支持      Device  Drivers--->Netowork device supprot-->Wireless LAN protocol

去掉WiFi支持后,編譯成的內核大小為1.28M可以使用了。

經過查閱資料得知,kprobe的使用,還需要有debugfs調試文件系統的配合,因此,需要讓系統啟動時,生成debugfs目錄


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM