linux oops 消息
大部分 bug 以解引用 NULL 指针或者使用其他不正确指针值来表现自己的. 此类 bug 通 常的输出是一个 oops 消息.
处理器使用的任何地址几乎都是一个虚拟地址, 通过一个复杂的页表结构映射为物理地址 (例外是内存管理子系统自己使用的物理地址). 当解引用一个无效的指针, 分页机制无法 映射指针到一个物理地址, 处理器发出一个页错误给操作系统. 如果地址无效, 内核无法 "页入"缺失的地址; 它(常常)产生一个 oops 如果在处理器处于管理模式时发生这个情况.
一个 oops 显示了出错时的处理器状态, 包括 CPU 寄存器内容和其他看来不可理解的信息. 消息由错误处理的 printk 语句产生( arch/*/kernel/traps.c )并且如同前面 "printk" 一节中描述的被分派.
我们看一个这样的消息. 这是来自在运行 2.6 内核的 PC 上一个 NULL 指针导致的结果. 这里最相关的信息是指令指针(EIP), 错误指令的地址.
Unable to handle kernel NULL pointer dereference at virtual address 00000000 printing eip:
d083a064
Oops: 0002 [#1] SMP
CPU: 0
EIP: 0060:[<d083a064>] Not tainted EFLAGS: 00010246 (2.6.6)
EIP is at faulty_write+0x4/0x10 [faulty]
eax: 00000000 ebx: 00000000 ecx: 00000000 edx: 00000000
esi: cf8b2460 edi: cf8b2480 ebp: 00000005 esp: c31c5f74 ds: 007b es: 007b ss: 0068
Process bash (pid: 2086, threadinfo=c31c4000 task=cfa0a6c0)
Stack: c0150558 cf8b2460 080e9408 00000005 cf8b2480 00000000 cf8b2460 cf8b2460 fffffff7 080e9408 c31c4000 c0150682 cf8b2460 080e9408 00000005 cf8b2480 00000000 00000001 00000005 c0103f8f 00000001 080e9408 00000005 00000005
Call Trace:
[<c0150558>] vfs_write+0xb8/0x130 [<c0150682>] sys_write+0x42/0x70 [<c0103f8f>] syscall_call+0x7/0xb
Code: 89 15 00 00 00 00 c3 90 8d 74 26 00 83 ec 0c b8 00 a6 83 d0
写入一个由坏模块拥有的设备而产生的消息, 一个故意用来演示失效的模块. faulty.c 的 write 方法的实现是琐细的:
ssize_t faulty_write (struct file *filp, const char user *buf, size_t count, loff_t *pos)
{
/* make a simple fault by dereferencing a NULL
pointer */
*(int *)0 = 0;
return 0;
}
如你能见, 我们这里做的是解引用一个 NULL 指针. 因为 0 一直是一个无效的指针值, 一个错误发生, 由内核转变为前面展示的 oops 消息. 调用进程接着被杀掉.
错误模块有不同的错误情况在它的读实现中:
ssize_t faulty_read(struct file *filp, char user *buf, size_t count, loff_t
*pos)
{
int ret;
char stack_buf[4];
/* Let's try a buffer overflow */ memset(stack_buf,
0xff, 20);
if (count > 4)
count = 4; /* copy 4
bytes to the user */ ret = copy_to_user(buf, stack_buf, count);
if (!ret)
return count; return ret;
}
这个方法拷贝一个字串到一个本地变量; 不幸的是, 字串长于目的数组. 当函数返回时导
致的缓存区溢出引起一次 oops . 因为返回指令使指令指针到不知何处, 这类的错误很难
跟踪, 并且你得到如下的:
EIP: 0010:[<00000000>]
Unable to handle kernel paging request at virtual address ffffffff
printing eip: ffffffff
Oops: 0000 [#5] SMP
CPU: 0
EIP: 0060:[<ffffffff>] Not tainted EFLAGS: 00010296 (2.6.6)
EIP is at 0xffffffff
eax: 0000000c ebx: ffffffff
ecx: 00000000 edx: bfffda7c esi: cf434f00 edi: ffffffff ebp: 00002000 esp: c27fff78 ds: 007b es: 007b
ss: 0068
Process head (pid: 2331,
threadinfo=c27fe000 task=c3226150)
Stack:
ffffffff bfffda70 00002000 cf434f20 00000001 00000286 cf434f00 fffffff7
bfffda70 c27fe000 c0150612 cf434f00 bfffda70 00002000 cf434f20 00000000
00000003 00002000 c0103f8f 00000003 bfffda70 00002000 00002000 bfffda70
Call Trace: [<c0150612>] sys_read+0x42/0x70
[<c0103f8f>] syscall_call+0x7/0xb Code: Bad EIP value.
这个情况, 我们只看到部分的调用堆栈( vfs_read 和 faulty_read 丢失 ), 内核抱怨一 个"坏
EIP 值". 这个抱怨和在开头列出的犯错的地址 (
ffffffff ) 都暗示内核堆栈已 被破坏.
通常, 当你面对一个 oops, 第一件事是查看发生问题的位置, 常常与调用堆栈分开列出. 在上面展示的第一个 oops, 相关的行是:
EIP is at
faulty_write+0x4/0x10 [faulty]
这里我们看到, 我们曾在函数 faulty_write, 它位于 faulty 模块( 在方括号中列出 的 ). 16 进制数指示指令指针是函数内 4 字节, 函数看来是 10 ( 16
进制 )字节长. 常常这就足够来知道问题是什么.
如果你需要更多信息, 调用堆栈展示给你如何得知在哪里坏事的. 堆栈自己是 16 机制形 式打印的;
做一点工作, 你经常可以从堆栈的列表中决定本地变量的值和函数参数. 有经 验的内核开发者可以从这里的某些模式识别中获益; 例如, 如果你看来自 faulty_read oops 的堆栈列表:
Stack: ffffffff bfffda70 00002000 cf434f20 00000001
00000286 cf434f00 fffffff7 bfffda70 c27fe000 c0150612 cf434f00 bfffda70
00002000 cf434f20 00000000 00000003 00002000 c0103f8f 00000003 bfffda70
00002000 00002000 bfffda70
堆栈顶部的 ffffffff 是我们坏事的字串的一部分. 在 x86 体系, 缺省地, 用户空间堆 栈开始于 0xc0000000; 因此, 循环值 0xbfffda70 可能是一个用户堆栈地址; 实际上, 它是传递给 read 系统调用的缓存地址, 每次下传过系统调用链时都被复制. 在
x86 (又 一次, 缺省地), 内核空间开始于 0xc0000000, 因此这个之上的值几乎肯定是内核空间的 地址, 等等.
最后, 当看一个 oops 列表, 一直监视本章开始讨论的"slab 毒害"值.
例如,如果你得到 一个内核 oops, 里面的犯错地址时 0xa5a5a5a5a5, 你几乎肯定 - 某个地方在初始化动 态内存.
请注意, 只在你的内核是打开 CONFIG_KALLSYMS 选项而编译时可以看到符号的调用堆栈. 否则, 你见到一个裸的, 16 机制列表, 除非你以别的方式对其解码, 它是远远无用的.
linux oops 消息的更多相关文章
- ARM Linux Oops使用小结(转)
出现Oops消息的大部分错误时因为对NULL指针取值或者因为用了其他不正确的指针值. Oops如何产生的解释如下: 由于处理器使用的地址几乎都是虚拟地址,这些地址通过一个被称为“页表”的结构被 ...
- linux进程间通信-消息队列
一 消息队列的介绍 消息队列提供了一种从一个进程向另一个进程发送一个数据块的方法. 每个数据块都被认为含有一个类型,接收进程可以独立地接收含有不同类型的数据结构. 我们可以通过发送消息来避免命名管道的 ...
- 依据linux Oops信息准确定位错误代码所在行
在linux下调tvp5150am1的过程中,遇到了一kernel oops,内容如下: [ 66.714603] Unable to handle kernel paging request a ...
- Linux进程间通信-消息队列(mqueue)
前面两篇文章分解介绍了匿名管道和命名管道方式的进程间通信,本文将介绍Linux消息队列(posix)的通信机制和特点. 1.消息队列 消息队列的实现分为两种,一种为System V的消息队列,一种是P ...
- 详解linux进程间通信-消息队列
前言:前面讨论了信号.管道的进程间通信方式,接下来将讨论消息队列. 一.系统V IPC 三种系统V IPC:消息队列.信号量以及共享内存(共享存储器)之间有很多相似之处. 每个内核中的 I P C结构 ...
- Linux进程间通信—消息队列
四.消息队列(Message Queue) 消息队列就是消息的一个链表,它允许一个或者多个进程向它写消息,一个或多个进程向它读消息.Linux维护了一个消息队列向量表:msgque,来表示系统中所有的 ...
- 分享一个Linux C++消息通信框架TCPSHM
由于本人从事行业关系,Linux环境下的低延迟通信是我关注的技术之一.要达到极端的低延迟,当然同机器内IPC比网络通信快,而Linux IPC方式中无疑是共享内存延迟最低.不过相对于TCP这种通用的通 ...
- linux IPC 消息队列
消息队列函数原型 在建立IPC通讯时(如消息队列,共享内存)必须建立一个ID值.通常情况下,这个ID值由ftok函数得到 #inlcude <sys/types.h> #include & ...
- linux oops调试
参考文章: arm 指令定位错误 https://blog.csdn.net/songcdut/article/details/41383483 linux mips指令学习 https://www. ...
随机推荐
- [idea]Error:java: invalid source release: 1.8 标签: idea 2017-02-24 15:50 961人阅读
最近用idea敲struts,虽然idea的界面很好看,代码提示也很强大,不过也的确是碰到了一些在eclipse上从来没有碰到过的问题,而且我发现,idea的错误,很多都是在外国的网站上提问的人比较多 ...
- iOS学习系列 - 扩展机制category与associative
iOS学习系列 - 扩展机制category与associative category与associative作为objective-c的扩展机制的两个特性,category即类型,可以通过它来扩展方 ...
- 解决/home磁盘空间不足问题
最近在Linux下做仿真实验,但是渐渐的发现,/home原来分配的空间不足.通过先建硬盘分区,然后挂载到/home文件的方法,在网上查了好多资料 建立分区并挂载分区http://www.se126.c ...
- hdu2041 dp
#include<stdio.h> int main() { int i,t,n; ]; dp[]=; dp[]=; dp[]=; ;i<=;i++) dp[i]=dp[i-]+dp ...
- ORA-03113: end-of-file on communication channel 解决方法
今天在测试数据库中对一个表插入了大量的数据, 导致数据库卡死 hang 住, 重启数据库后报错如下: C:\Documents and Settings\davidd>sqlplus " ...
- 笔记: CC2540 和 CC2541 的区别
CC2540 和 CC2541 的区别 CC2540 和 CC2541 是 BLE 低功耗蓝牙芯片,使用的是 51 内核. CC2540 有 USB 接口 CC2541 无. 价格上最早是 CC254 ...
- python ASCII编码集
- axios细节之绑定到原型和axios的defaults的配置属性
把axios绑定到原型 vue开发者一套很好用的实践,一般来说,实践如果能够让大部分人都接受,会逐渐成为一个默认的标准. // 把axios配置到原型上 Vue.prototype.$axios = ...
- 5G时代-计算机和网络的又一个春天
预言 5G时代的到来计算机和网络即将再次变成热门,计算机和网络的前途将不可限量,就经济学思想来说一定是最具有经济价值的技术,计算机和网络将蓬勃发展,迅速膨胀,经济价值变得极高.将成为科技和智能生活的最 ...
- svn总结 标签: svn开源软件 2015-05-09 17:31 513人阅读 评论(11) 收藏
说到SVN,就不得不说CVS,CVS 是一个C/S系统,是一个常用的代码版本控制软件.主要在开源软件管理中使用.与它相类似的代码版本控制软件有subversion.多个开发人员通过一个中心版本控制系统 ...