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,电信活动可以直接通过营业厅查询。