Linux Kernel Panic報錯解決思路

Linux雖然沒有藍屏現象,不過Kernel報錯有時也會讓人頭疼。有時重啓後正常,linux系統運行一段時間後又down了,總不能出現問題就reboot啊。我從網上搜集一下資料,整理了出來,希望大家能在評論與我交流您的看法與經驗。

什麼是Kernel Panic?

wiki:

A kernel panic is an action taken by an operating system upon detecting an internal fatal error from which it cannot safely recover. The term is largely specific to Unix and Unix-like systems; for Microsoft Windowsoperating systems the equivalent term is “Bug check” (or, colloquially, “Blue Screen of Death“).

The kernel routines that handle panics (in AT&T-derived and BSD Unix source code, a routine known as panic()) are generally designed to output an error message to the console, dump an image of kernel memory to disk for post-mortemdebugging and then either wait for the system to be manually rebooted, or initiate an automatic reboot. The information provided is of highly technical nature and aims to assist a system administrator or software developer in diagnosing the problem.

Attempts by the operating system to read an invalid or non-permitted memory address are a common source of kernel panics. A panic may also occur as a result of a hardware failure or a bug in the operating system. In many cases, the operating system could continue operation after memory violations have occurred. However, the system is in an unstable state and rather than risking security breaches and data corruption, the operating system stops to prevent further damage and facilitate diagnosis of the error.

The kernel panic was introduced in an early version of Unix and demonstrated a major difference between the design philosophies of Unix and its predecessor Multics. Multics developer Tom van Vleck recalls a discussion of this change with Unix developer Dennis Ritchie:

I remarked to Dennis that easily half the code I was writing in Multics was error recovery code. He said, “We left all that stuff out. If there’s an error, we have this routine called panic, and when it is called, the machine crashes, and you holler down the hall, ‘Hey, reboot it.’”[1]

The original panic() function was essentially unchanged from Fifth Edition UNIX to the VAX-based UNIX 32V and output only an error message with no other information, then dropped the system into an endless idle loop. As the Unixcodebase was enhanced, the panic() function was also enhanced to dump various forms of debugging information to the console.

panic是英文中是驚慌的意思,Linux Kernel panic正如其名,linux kernel不知道如何走了,它會儘可能把它此時能獲取的全部信息都打印出來。

有兩種主要類型kernel panic:

1.hard panic(也就是Aieee信息輸出)
2.soft panic (也就是Oops信息輸出)

常見Linux Kernel Panic報錯內容:

Kernel panic-not syncing fatal exception in interrupt
kernel panic – not syncing: Attempted to kill the idle task!
kernel panic – not syncing: killing interrupt handler!
Kernel Panic – not syncing:Attempted to kill init !

什麼會導致Linux Kernel Panic?

只有加載到內核空間的驅動模塊才能直接導致kernel panic,你可以在系統正常的情況下,使用lsmod查看當前系統加載了哪些模塊。
除此之外,內建在內核裏的組件(比如memory map等)也能導致panic。

因爲hard panic和soft panic本質上不同,因此我們分別討論。

hard panic

一般出現下面的情況,就認爲是發生了kernel panic:

  1. 機器徹底被鎖定,不能使用

  2. 數字鍵(Num Lock),大寫鎖定鍵(Caps Lock),滾動鎖定鍵(Scroll Lock)不停閃爍。

  3. 如果在終端下,應該可以看到內核dump出來的信息(包括一段”Aieee”信息或者”Oops”信息)

  4. 和Windows藍屏相似

原因:

對於hard panic而言,最大的可能性是驅動模塊的中斷處理(interrupt handler)導致的,一般是因爲驅動模塊在中斷處理程序中訪問一個空指針(null pointre)。一旦發生這種情況,驅動模塊就無法處理新的中斷請求,最終導致系統崩潰。

信息收集
根據panic的狀態不同,內核將記錄所有在系統鎖定之前的信息。因爲kenrel panic是一種很嚴重的錯誤,不能確定系統能記錄多少信息,下面是一些需要收集的關鍵信息,他們非常重要,因此儘可能收集全,當然如果系統啓動的時候就kernel panic,那就無法只知道能收集到多少有用的信息了。

  1. /var/log/messages: 幸運的時候,整個kernel panic棧跟蹤信息都能記錄在這裏。

  2. 應用程序/庫 日誌: 可能可以從這些日誌信息裏能看到發生panic之前發生了什麼。

  3. 其他發生panic之前的信息,或者知道如何重現panic那一刻的狀態

  4. 終端屏幕dump信息,一般OS被鎖定後,複製,粘貼肯定是沒戲了,因此這類信息,你可以需要藉助數碼相機或者原始的紙筆工具了。

如果kernel dump信息既沒有在/var/log/message裏,也沒有在屏幕上,那麼嘗試下面的方法來獲取(當然是在還沒有死機的情況下):

  1. 如果在圖形界面,切換到終端界面,dump信息是不會出現在圖形界面的,甚至都不會在圖形模式下的虛擬終端裏。

  2. 確保屏幕不黑屏,可以使用下面的幾個方法:

    • setterm -blank 0

    • setterm -powerdown 0

    • setvesablank off

  3. 從終端,拷貝屏幕信息(方法見上)

完整棧跟蹤信息的排查方法

棧跟蹤信息(stack trace)是排查kernel panic最重要的信息,該信息如果在/var/log/messages日誌裏當然最好,因爲可以看到全部的信息,如果僅僅只是在屏幕上,那麼最上面的信息可能因爲滾屏消失了,只剩下棧跟蹤信息的一部分。如果你有一個完整棧跟蹤信息的話,那麼就可能根據這些充分的信息來定位panic的根本原因。要確認是否有一個足夠的棧跟蹤信息,你只要查找包含”EIP”的一行,它顯示了是什麼函數和模塊調用時導致panic。

使用內核調試工具(kenrel debugger ,aka KDB)

如果跟蹤信息只有一部分且不足以用來定位問題的根本原因時,kernel debugger(KDB)就需要請出來了。
KDB編譯到內核裏,panic發生時,他將內核引導到一個shell環境而不是鎖定。這樣,我們就可以收集一些與panic相關的信息了,這對我們定位問題的根本原因有很大的幫助。

使用KDB需要注意,內核必須是基本核心版本,比如是2.4.18,而不是2.4.18-5這樣子的,因爲KDB僅對基本核心有效。

soft panic

症狀:

  1. 沒有hard panic嚴重

  2. 通常導致段錯誤(segmentation fault)

  3. 可以看到一個oops信息,/var/log/messages裏可以搜索到’Oops’

  4. 機器稍微還能用(但是收集信息後,應該重啓系統)

原因:

凡是非中斷處理引發的模塊崩潰都將導致soft panic。在這種情況下,驅動本身會崩潰,但是還不至於讓系統出現致命性失敗,因爲它沒有鎖定中斷處理例程。導致hard panic的原因同樣對soft panic也有用(比如在運行時訪問一個空指針)

信息收集:
當soft panic發生時,內核將產生一個包含內核符號(kernel symbols)信息的dump數據,這個將記錄在/var/log/messages裏。爲了開始排查故障,可以使用ksymoops工具來把內核符號信息轉成有意義的數據。

爲了生成ksymoops文件,需要:

  • 從/var/log/messages裏找到的堆棧跟蹤文本信息保存爲一個新文件。確保刪除了時間戳(timestamp),否則ksymoops會失敗。

  • 運行ksymoops程序(如果沒有,請安裝)

  • 詳細的ksymoops執行用法,可以參考ksymoops(8)手冊。

Kernel panic實例:

今天就遇到 一個客戶機器內核報錯:“Kernel panic-not syncing fatal exception”

重啓後正常,幾個小時後出現同樣報錯,系統down了,有時重啓後可恢復有時重啓後仍然報同樣的錯誤。

我先來解釋一下什麼是fatal exception?

“致命異常(fatal exception)表示一種例外情況,這種情況要求導致其發生的程序關閉。通常,異常(exception)可能是任何意想不到的情況(它不僅僅包括程序錯誤)。致命異常簡單地說就是異常不能被妥善處理以至於程序不能繼續運行。

軟件應用程序通過幾個不同的代碼層與操作系統及其他應用程序相聯繫。當異常(exception)在某個代碼層發生時,爲了查找所有異常處理的代碼,各個代碼層都會將這個異常發送給下一層,這樣就能夠處理這種異常。如果在所有層都沒有這種異常處理的代碼,致命異常(fatal exception)錯誤信息就會由操作系統顯示出來。這個信息可能還包含一些關於該致命異常錯誤發生位置的祕密信息(比如在程序存儲範圍中的十六進制的位置)。這些額外的信息對用戶而言沒有什麼價值,但是可以幫助技術支持人員或開發人員調試程序。

當致命異常(fatal exception)發生時,操作系統沒有其他的求助方式只能關閉應用程序,並且在有些情況下是關閉操作系統本身。當使用一種特殊的應用程序時,如果反覆出現致命異常錯誤的話,應將這個問題報告給軟件供應商。 ”

而且此時鍵盤無任何反應,必然使用reset鍵硬重啓。

panic.c源文件有個方法,當panic掛起後,指定超時時間,可以重新啓動機器

方法:

#vi /etc/sysctl.conf  添加

kernel.panic = 20 #panic error中自動重啓,等待timeout爲20秒
kernel.sysrq=1 #激活Magic SysRq  否則,鍵盤鼠標沒有響應

按住 [ALT]+[SysRq]+[COMMAND], 這裏SysRq是Print SCR鍵,而COMMAND按以下來解釋!

b – 立即重啓
e – 發送SIGTERM給init之外的系統進程
o – 關機
s – sync同步所有的文件系統
u – 試圖重新掛載文件系統

配置一下以防萬一。

很多網友安裝linux出現“Kernel panic-not syncing fatal exception in interrupt”是由於網卡驅動原因。

解決方法:將選項“Onboard Lan”的選項“Disabled”,重啓從光驅啓動即可。

等安裝完系統之後,再進入BIOS將“Onboard Lan”的選項給“enable”,下載相應的網卡驅動安裝。

如出現以下報錯:

init() r8168 …

… …

 … :Kernel panic: Fatal exception

r8168是網卡型號。

在BIOS中禁用網卡,從光驅啓動安裝系統。再從網上下載網卡驅動安裝。

#tar vjxf  r8168-8.014.00.tar.bz2

# make  clean  modules (as root or with sudo)

# make  install

# depmod  -a

# modprobe  r8168

安裝好系統後reboot進入BIOS把網卡打開。

另有網友在Kernel panic出錯信息中看到“alc880”,這是個聲卡類型。嘗試着將聲卡關閉,重啓系統,搞定。

安裝linux系統遇到安裝完成之後,無法啓動系統出現Kernel panic-not syncing fatal exception。很多情況是由於板載聲卡、網卡、或是cpu 超線程功能(Hyper-Threading )引起的。這類問題的解決辦法就是先查看錯誤代碼中的信息,找到錯誤所指向的硬件,將其禁用。系統啓動後,安裝好相應的驅動,再啓用該硬件即可。
另外出現“Kernel Panic — not syncing: attempted to kill init”和“Kernel Panic — not syncing: attempted to kill idle task”有時把內存互相換下位置或重新插拔下可以解決問題。

本文至此結束,希望大家能在評論中交流您的看法和經歷。


原文出自:http://blog.51osos.com/linux/linux-kernel-panic

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章