Kernel panic是什么
panic是英文中是驚慌的意思,linux
kernel
panic正如其名,linux
kernel不知道如何走了,它會盡可能把它此時能獲取的全部信息都打印出來。
有兩種主要類型kernel
panic,
1.hard
panic(也就是aieee信息輸出)
2.soft
panic
(也就是oops信息輸出)
什么時候會kernel panic?
什么時候可能出現內核崩潰,kernrl panic呢?
Linux在中斷處理程序中,它不處于任何一個進程上下文,如果使用可能睡眠的函數,則系統調度會被破壞,導致kernel panic。因此,在中斷處理程序中,是不能使用有可能導致睡眠的函數(例如信號量等)。
在中斷發起的軟中斷中,其上下文環境有可能是中斷上下文,同理,也不能調用可能導致睡眠的函數。軟中斷執行時,全局中斷是打開的,而中斷程序執行時,全局中斷是禁止的。
軟中斷除了系統調度進入點,當軟中斷數量頻繁時,內核中有一個專門的軟中斷的后臺程序daemon來處理其事務。
還有內核堆棧溢出,或者指針異常訪問時,也會出現kernel panic。
堆棧溢出:程序循環或者多層嵌套的深度過多時,可能會導致棧溢出。
顯而易見,除0異常、內存訪問越界、緩沖區溢出等錯誤時,當這些事件發生在應用程序時,Linux內核的異常處理機制可以對這些由應用程序引起的情況予以處理。當應用程序出現不可恢復性錯誤時,Linux內核可以僅僅終止產生錯誤的應用程序,而不影響其他程序。如果上述操作發生在內核空間,就會引起kernel panic。
還有內核陷入死鎖狀態,自旋鎖嵌套、在內核線程中,存在死循環的操作等等都會引起kermel panic。
如何產生 kernel panic
Linux kernel panic是很難定位和排查的重大故障,一旦系統發生了kernel panic,相關的日志信息非常少,而一種常見的排查方法—重現法–又很難實現,因此遇到kernel panic的問題,一般比較頭疼。
沒有一個萬能和完美的方法來解決所有的kernel panic問題,這篇文章僅僅只是給出一些思路,一來如何解決kernel panic的問題,二來可以盡可能減少發生kernel panic的機會。
什么是kernel panic
就像名字所暗示的那樣,它表示Linux kernel走到了一個不知道該怎么走下一步的狀況,一旦到這個情況,kernel就盡可能把它此時能獲取的全部信息都打印出來,至于能打印出多少信息,那就看是那種情況導致它panic了。
有兩種主要類型kernel panic:
1.hard panic(也就是Aieee信息輸出)
2.soft panic (也就是Oops信息輸出)
什么能導致kernel panic
只有加載到內核空間的驅動模塊才能直接導致kernel panic,你可以在系統正常的情況下,使用lsmod查看當前系統加載了哪些模塊。
除此之外,內建在內核里的組件(比如memory map等)也能導致panic。
因為hard panic和soft panic本質上不同,因此我們分別討論。
如何排查hard panic
一般出現下面的情況,就認為是發生了kernel panic:
機器徹底被鎖定,不能使用
數字鍵(Num Lock),大寫鎖定鍵(Caps Lock),滾動鎖定鍵(Scroll Lock)不停閃爍。
如果在終端下,應該可以看到內核dump出來的信息(包括一段”Aieee”信息或者”Oops”信息)
和Windows藍屏相似
原因:
對于hard panic而言,最大的可能性是驅動模塊的中斷處理(interrupt handler)導致的,一般是因為驅動模塊在中斷處理程序中訪問一個空指針(null pointre)。一旦發生這種情況,驅動模塊就無法處理新的中斷請求,最終導致系統崩潰。
信息收集
根據panic的狀態不同,內核將記錄所有在系統鎖定之前的信息。因為kenrel panic是一種很嚴重的錯誤,不能確定系統能記錄多少信息,下面是一些需要收集的關鍵信息,他們非常重要,因此盡可能收集全,當然如果系統啟動的時候就 kernel panic,那就無法只知道能收集到多少有用的信息了。
/var/log/messages: 幸運的時候,整個kernel panic棧跟蹤信息都能記錄在這里。
應用程序/庫 日志: 可能可以從這些日志信息里能看到發生panic之前發生了什么。
其他發生panic之前的信息,或者知道如何重現panic那一刻的狀態
終端屏幕dump信息,一般OS被鎖定后,復制,粘貼肯定是沒戲了,因此這類信息,你可以需要借助數碼相機或者原始的紙筆工具了。
如果kernel dump信息既沒有在/var/log/message里,也沒有在屏幕上,那么嘗試下面的方法來獲取(當然是在還沒有死機的情況下):
如果在圖形界面,切換到終端界面,dump信息是不會出現在圖形界面的,甚至都不會在圖形模式下的虛擬終端里。
確保屏幕不黑屏,可以使用下面的幾個方法:
tterm -blank 0
tterm -powerdown 0
tvesablank off
從終端,拷貝屏幕信息(方法見上)
完整棧跟蹤信息的排查方法
棧跟蹤信息(stack trace)是排查kernel panic最重要的信息,該信息如果在/var/log/messages日志里當然最好,因為可以看到全部的信息,如果僅僅只是在屏幕上,那么最上面的 信息可能因為滾屏消失了,只剩下棧跟蹤信息的一部分。如果你有一個完整棧跟蹤信息的話,那么就可能根據這些充分的信息來定位panic的根本原因。要確認 是否有一個足夠的棧跟蹤信息,你只要查找包含”EIP”的一行,它顯示了是什么函數和模塊調用時導致panic。大概就像下面這個例子一樣:
EIP is at _dlgn_tevmask [streams-dlgnDriver] 0xe
hard panic的一個完整跟蹤信息例子:
Unable to handle kernel NULL pointer dereference at virtual address 0000000c
printing eip:
f89e568a
*pde = 32859001
*pte = 00000000
Oops: 0000
Kernel 2.4.9-31enterpri
CPU: 1
EIP: 0010:[<f89e568a>] Tainted: PF
EFLAGS: 00010096
EIP is at _dlgn_tevmask [streams-dlgnDriver] 0xe
eax: 00000000 ebx: f65f5410 ecx: f5e16710 edx: f65f5410
esi: 00001ea0 edi: f5e23c30 ebp: f65f5410 esp: f1cf7e78
ds: 0018 es: 0018 ss: 0018
Process pwcallmgr (pid: 10334, stackpage=f1cf7000)
Stack: 00000000 c01067fa 00000086 f1cf7ec0 00001ea0 f5e23c30 f65f5410 f89e53ec
f89fcd60 f5e16710 f65f5410 f65f5410 f8a54420 f1cf7ec0 f8a4d73a 0000139e
f5e16710 f89fcd60 00000086 f5e16710 f5e16754 f65f5410 0000034a f894e648
Call Trace: [tup_sigcontext+218/288] tup_sigcontext [kernel] 0xda
Call Trace: [<c01067fa>] tup_sigcontext [kernel] 0xda
[<f89e53ec>] dlgnwput [streams-dlgnDriver] 0xe8
[<f89fcd60>] Sm_Handle [streams-dlgnDriver] 0×1ea0
[<f8a54420>] intdrv_lock [streams-dlgnDriver] 0×0
[<f8a4d73a>] Gn_Maxpm [streams-dlgnDriver] 0×8ba
[<f89fcd60>] Sm_Handle [streams-dlgnDriver] 0×1ea0
[<f894e648>] lis_safe_putnext [streams] 0×168
[<f8a7b098>] __insmod_streams-dvbmDriver_S.bss_L117376 [streams-dvbmDriver] 0xab8
[<f8a78821>] dvbmwput [streams-dvbmDriver] 0×6f5
[<f8a79f98>] dvwinit [streams-dvbmDriver] 0×2c0
[<f894e648>] lis_safe_putnext [streams] 0×168
[<f893e6d8>] lis_strputpmsg [streams] 0×54c
[<f895482e>] __insmod_streams_S.rodata_L35552 [streams] 0×182e
[<f8951227>] sys_putpmsg [streams] 0×6f
[system_call+51/56] system_call [kernel] 0×33
[<c010719b>] system_call [kernel] 0×33
Nov 28 12:17:58 talus kernel:
Nov 28 12:17:58 talus kernel:
Code: 8b 70 0c 8b 06 83 f8 20 8b 54 24 20 8b 6c 24 24 76 1c 89 5c
完整棧信息無效的排查方法
如果只有部分跟蹤信息,要快速定位問題的根本原因就變得很難,因為沒有明顯的信息來告訴我們是哪個模塊或者函數的調用導致了內核panic,你可能只能看到kernel最后的一些指令。這種情況下,要盡可能多的收集信息,包括程序日志,庫的跟蹤信息,故障重現的步驟等。
Hard panic 部分跟蹤信息例子(沒有EIP信息):
[<c01e42e7>] ip_rcv [kernel] 0×357
[<f8a179d5>] sramintr [streams_dlgnDriver] 0×32d
[<f89a3999>] lis_spin_lock_irqsave_fcn [streams] 0×7d
[<f8a82fdc>] inthw_lock [streams_dlgnDriver] 0×1c
[<f8a7bad8>] pwswtbl [streams_dlgnDriver] 0×0
[<f8a15442>] dlgnintr [streams_dlgnDriver] 0×4b
[<f8a7c30a>] Gn_Maxpm [streams_dlgnDriver] 0×7ae
[<c0123bc1>] __run_timers [kernel] 0xd1
[<c0108a6e>] handle_IRQ_event [kernel] 0×5e
[<c0108c74>] do_IRQ [kernel] 0xa4
[<c0105410>] default_idle [kernel] 0×0
[<c0105410>] default_idle [kernel] 0×0
[<c022fab0>] call_do_IRQ [kernel] 0×5
[<c0105410>] default_idle [kernel] 0×0
[<c0105410>] default_idle [kernel] 0×0
[<c010543d>] default_idle [kernel] 0×2d
[<c01054c2>] cpu_idle [kernel] 0×2d
[<c011bb86>] __call_console_drivers [kernel] 0×4b
[<c011bcfb>] call_console_drivers [kernel] 0xeb
Code: 8b 50 0c 85 d2 74 31 f6 42 0a 02 74 04 89 44 24 08 31 f6 0f
<0> Kernel panic: Aiee, killing interrupt handler!
In interrupt handler – not syncing
使用內核調試工具(kenrel debugger ,aka KDB)
如果跟蹤信息只有一部分且不足以用來定位問題的根本原因時,kernel debugger(KDB)就需要請出來了。
KDB編譯到內核里,panic發生時,他將內核引導到一個shell環境而不是鎖定。這樣,我們就可以收集一些與panic相關的信息了,這對我們定位問題的根本原因有很大的幫助。
使用KDB需要注意,內核必須是基本核心版本,比如是2.4.18,而不是2.4.18-5這樣子的,因為KDB僅對基本核心有效。
如何排查soft panic
癥狀:
沒有hard panic嚴重
通常導致段錯誤(gmentation fault)
可以看到一個oops信息,/var/log/messages里可以搜索到’Oops’
機器稍微還能用(但是收集信息后,應該重啟系統)
原因:
凡是非中斷處理引發的模塊崩潰都將導致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)手冊。
下面是一個soft panic的oopsg跟蹤例子:
Code: 8b 70 0c 50 e8 69 f9 f8 ff 83 c4 10 83 f8 08 74 35 66 c7 47
EIP; f89ba71e <[streams-dlgnDriver]_dlgn_tidlestate+1e/8c>
Trace; f8951bd6 <[streams]lis_wakeup_clo+86/110>
Trace; f8a2705c <[streams-dlgnDriver]__module_parm_r4_feature+280/1453>
Trace; f8a27040 <[streams-dlgnDriver]__module_parm_r4_feature+264/1453>
Trace; f89b9198 <[streams-dlgnDriver]dlgnwput+e8/204>
linux啟動故障 kernel panic
1、重新啟動linux 系統,看見如圖見面迅速按E鍵
2、看見如圖界面在按E鍵編輯
3、如圖界面使用上下鍵選擇第二個在按E鍵
4、在最后一行后面添加 enforcing=0 按回車保存退出
5、在此頁面按B鍵重新啟動即可
你好,Linux系統啟動報kernelpanic- not syncing: attempted to kil init! 網上的辦法我試了沒有解決。
尊敬的用戶您好:
在啟動linux時,出現上面這個錯誤,許多情況下是因為,沒有在grub.conf(或者你沒有安裝grub,而用的是grub4dos的menu.lst文件)文件,沒有指定根文件系統.
Do not forget that you have to specify a root partion to the kernel.(Grub 手冊)
這里給出一個例子,一看你就明白了。
timeout=10
defalut=0
title Redhat Enterpri Linux 5
kernel (hd0,7)/boot/vmlinuz-2.6.18-194.el5 ro root=/dev/sda8 rhgb quiet
initrd (hd0,7)/boot/initrd-2.6.18-194.el5.img
ro 參數告訴內核以只讀方式加載根文件系統,以便進行文件系統完整性檢查;
rhgb 指的是redhat graphics boot,圖形界面啟動顯示;
quiet指的是,僅列出簡要的信息。
其實,只要加上上面黑體的那句就可以啟動了。
中國電信提供最優質的網絡通訊服務,老友換新機,網齡抵現金,百兆寬帶免費體驗,超清電視iTV,電信活動可以直接通過營業廳查詢。