linnx内核出现段错误(segment fault)的调试方法
来源:互联网 发布:百年战争 知乎 编辑:程序博客网 时间:2024/05/22 02:08
当你的程序在运行的过程中访问到空指针,那么linux系统就会出现非法访问内存错误,通常称为段错误(segmeng fault)
段错误分为用户态和内核态两种情况:
当用户态程序出现访问非法地址出现段错误时,程序退出并答应“segment fault”提示信息,这种情况下不会导致系统崩溃,修改好程序之后还可以再次运行。
但是发生在内核态的段错误,会导致系统崩溃,死机现象,要再次用就只能重启机器才可以。所以应尽量避免内核台访问非法指针出现段错误。在编写内核态代码的时候,在读写指针之前要养成先判断指针是否有效然后在赋值的习惯。
但是如果真的在内核台出现的段错误,那么如何快速有效的定位段错误出现的位置。下面介绍两种方法帮助快捷找出段错误所在位置。
1.使用xxx-xxx-objdump命令把你的运行的代码反汇编。
我的实验平台是ba,根据不同的平台选用不用的交叉工具链
Ba-linux-objdump -D -S exe(.o&hex……)> objdump.txt
上面的命令解释:
-D 反汇编所有节的内容
-S 尽可能显示与反汇编混合的源代码
下面是我对自己可运行文件的反汇编:
static int mfvd_in_ring_release_cb(int ringpair_id, uint32_t optdata)
{
偏移地址 机器码 汇编指令
0: cd 41 3f ff b.sw -0x4(r1),r10
4: 05 41 b.mov r10,r1
struct mfvd_stream_dev *dev = (struct mfvd_stream_dev *)optdata;
dev->in_ring.id = -1;
6: 00 ef b.movi r7,-0x1
8: cc e4 3d 80 b.sw 0x1bc(r4),r7
return 0;
}
c: 00 60 b.movi r3,0x0
e: cd 41 7f ff b.lwz r10,-0x4(r1)
12: 47 d2 48 b.jr r9
00000015 <mfvd_read>:
return 0;
}
2.根据内核态出现段错误时打印的信息分析段错误
a)、当前pc寄存器的值
当你的程序出现段错误时,根据内核的段错误处理机制一边会打印错误的提示信息。这些信息通常包括,当前之前指针,堆栈指针,最后运行的机器码等。
Oops#: 0000
CPU #: 0
PC: d0c7f54d SR: 00008a7f SP: c42a9530
GPR00: 00000000 GPR01: c42a9530 GPR02: c033e000 GPR03: c42a9938
GPR04: 00097e00 GPR05: 0000032a GPR06: 00000bb8 GPR07: 00000000
GPR08: c42a9d3c GPR09: d0c7f689 GPR10: c42a9530 GPR11: 0000032a
GPR12: c434bd14 GPR13: 0000000c GPR14: 00097e00 GPR15: 00000000
GPR16: c42a9538 GPR17: 00097e00 GPR18: 00000001 GPR19: c434860c
GPR20: 00000003 GPR21: 00000001 GPR22: 00000010 GPR23: 00000000
GPR24: 0000032a GPR25: 00000040 GPR26: 00000004 GPR27: c42a9d38
GPR28: 00000004 GPR29: c42a8000 GPR30: c4348724 GPR31: 00000000
RES: 00000000 oGPR3: c42a9938 syscallno: c42a94c0
如上面所示,PC:d0c7f54d,这个值就是你运行出错时的地址,根据这个地址,去反汇编文件objdum.txt中查找这个地址的位置,找出该位置对应的机器码源代码,那么你就可以清除知道你代码出错的位置了。
b)、出现段错误之后打印的机器码
=======================
Code: ff 6f 46 40 67 39 33 41 07 36 02 e0 41 18 30 cd 41 7f ff 47 d2 48 08 99 (24) c4 c0 6c c6
a1 24 e4 40 6c e7 c0 60 c6 39 24 e4 80 34 e7 c0 6c e7 d0
上面的打印信息是内错出错之后,打印出来的最后执行的那一段机器码。同样道理,在反汇编文件objdunp.txt中查找这些机器码出现的位置,那么就可以确定源代码出错的位置。
- linnx内核出现段错误(segment fault)的调试方法
- 使用gdb调试段错误(segment fault)
- 使用gdb调试段错误(segment fault)
- 使用gdb调试段错误(segment fault) .
- 使用gdb调试段错误(segment fault)
- 使用gdb调试段错误(segment fault)
- 使用gdb调试段错误(segment fault)
- 嵌入式 使用gdb调试段错误(segment fault)
- 使用gdb调试段错误(segment fault)
- 使用gdb调试段错误(segment fault)
- 嵌入式 使用gdb调试段错误(segment fault)
- Linux 段错误调试Segment Fault
- 段错误的调试方法 Segmentation fault
- segment fault 的调试方法
- 段错误(Segment Fault!)莫名的问题 by fish
- 段错误(Segment Fault!)莫名的问题
- 段错误(segment fault)的几种原因
- c++中的段错误(segment fault)
- Windows 7下卸载Oracle 10g
- jni 签名获取
- 使用TortoiseSVN搭建本地的版本控制库
- 浅谈EABI和OABI
- 在鼠标右键添加程序
- linnx内核出现段错误(segment fault)的调试方法
- 腾讯1亿用户在线背后的技术挑战
- android 文件的下载
- 秋天了,腱鞘炎发作,无法打字了
- (转)百度Android开发面试题
- win7(x64) + VMware8(Ubuntu10.04) minicom 设置 问题解决
- [过来人经验] 你为什么还没有好工作
- Spring + BlazeDS RC1集成指南
- Assert API