Linux故障没有panic就直接宕机了
一般情况下,Linux内核在遇到不可恢复的故障时,就会panic,类似Windows的蓝屏,不管是panic还是蓝屏,总是会在屏幕上打印一些东西,这就是 最后一屏有用的信息。
这最后一屏信息非常重要,它可以帮助我们定位引发系统故障的潜在的bug。事实上,很多时候,对于开源系统而言,这最后一屏信息甚至比vmcore之类的更加有用且轻量级。比如根据堆栈和出错的函数位置,基本对着代码就能看出个究竟。
那么,问题是,是不是Linux系统遇到不可恢复的故障,总是会panic呢?有没有什么情况下是直接就宕机而没有任何遗言呢?或者说故障太严重,以至于根本就没有任何机会留下任何信息就宕机了。
肯定是有的。
比如电源故障,掉电之类,计算机赖以生存的能源都没有了。还有就是主板上泼水之类,直接破坏硬件组织。不过这些都是系统外部的严重事件,我指的是,只给你个键盘,你能否写出一个瞬间宕机的程序呢?
当然了,前提条件必须是故障触发,而不能是调用底层的reboot,halt等接口。换句话说,你能否通过 踩内存 的方式让机器绕过panic直接宕机或者重启呢?
肯定可以。如何来做呢?让我们想一下panic函数赖以执行的条件是什么。
我们知道,在现代操作系统中,即便是内核里的panic函数也是用虚拟地址取指载入CPU来执行的,也就是说,panic函数的指令是通过虚拟地址来寻址的,在现代操作系统中,虚拟地址和物理地址之间的纽带就是MMU,虚拟地址通过页表翻译成物理地址发射到地址总线去内存中取数据,这一切工作的前提,全凭一个指向当前进程页表的CR3寄存器。
panic函数的指令也是靠CR3寄存器指示的页目录逐渐被找到然后载入CPU去执行的,那么很简单,只需要破坏掉CR3寄存器即可。即切断虚拟地址和物理内存的纽带!
写个模块,init函数里包含下面的函数:
unsigned long var = 0; asm volatile ("mov %0, %%cr3"::"r"(var));
系统秒崩。你试试。
不过,你直接操作寄存器,不能算数,那就换一种方法。我们知道在进程切换的时候,会执行load CR3的动作,类似上面的汇编代码,将新的进程的页目录物理地址载入CR3寄存器,那么给它改了就行了啊:
list_for_each(pos, &ts->tasks) { p = list_entry(pos, struct task_struct,tasks); if (p->pid == 1339) { // 随便一个非当前insmod进程即可 p->mm->pgd = PAGE_OFFSET + 123456; } }
当进程切换到1339号时,系统秒崩。
我们换个角度,如果在内核空间发生了踩内存,恰恰把某个task的pgd给改成了一个非页目录的地址,会发生什么呢?当然是秒崩咯。
所以这类bug非常难以定位,因为你连最后一屏信息都拿不到,更别说什么vmcore了,虚拟地址和物理内存之间的纽带就像大动脉一样被砍掉,系统没有任何机会去留下哪怕一点点信息,因为留下哪怕一点点信息这件事也是指令,也需要虚拟地址去寻址的。
突然就又想到了panic和oops字面的意思。
panic是惊恐不知所措的意思,既然不知所措了,那就待在原地最好最安全,所以panic的最后是一个无限的循环,然后里面就是闪灯之类的操作。
oops是 哎哟 的意思,就好像不知怎么回事有人背后撞了你一下,你毫无防备和预期,然后感觉到了一点疼,哎哟一声。这个oops显然没有panic严重。
可是有些时候,oops的同时也伴随着panic,这也可以理解。背后被撞了一下,那就哎哟一声罢了,这就是oops,如果背后被捅了一刀,或者后心窝被打了一枪,那肯定就是先哎哟一声,然后惊恐倒地,身体发生了预期之外不可恢复的故障,就是oops和panic了。
再举一个例子,前些天Robin Li老板被浇水,那就只是oops,而换成几十年前的肯尼迪,那就是oops/panic了。
那么,什么是load 0 to CR3呢?斩首吗?貌似也不,因为研究表明身首分离后,人还是有意识的,那么到底是什么能让人一瞬间就结束呢?目前貌似还没有还不知道。
浙江温州皮鞋湿,下雨进水不会胖。
- linux网卡故障:弹出界面eth0: 错误:没有找到合适的设备:没有找到可用于链接System eth0 的
- Linux访问网站时,http://.../无法解析,出现了某些故障(-5-没有与主机名关联的地址)
- 『Linux运维笔记----网卡故障:弹出界面eth0: 错误:没有找到合适的设备』
- Torvalds说他没有任何Linux的长远规划
- linux启动过程及故障排除
- U盘安装Linux CentOS 6.5及遇到故障 64位操作系统及禁用ipv6 ,CentOS7卸载OpenJDK安装Oracle JDK
- Linux 只可以找到 lo 网卡,没有eth0 or eth1网卡的解决方法
- Linux终端打开后没有内容显示的解决办法
- 【Linux开发】直接渲染管理
- 多线程 list没有锁好导致的 不安全宕机问题
- Window直接执行远程Linux命令
- Linux_终端直接执行py文件,不需要python命令
- window下直接格式化linux导致开不了机
- 彻底解决Linux索引节点(inode)用满导致故障的方法
- linux分析和排查系统故障
- Linux下c直接插入排序算法
- Android --- 64bit Ubuntu系统下 搭建JDK和SDK环境后,出现android-sdk-linux/platform-tools/adb: 没有那个文件或目录错误
- # 【ARM-Linux开发】在Win7的电脑上直接运行安装Ubuntu14.04发生的问题 标签(空格分隔): 【Linux开发】 --- > 一段时间以来,一直是在Windows上安装虚拟机
- Linux的直接I/O机制
- Linux下cp直接覆盖不提示的方法!