kernel segfault rip rsp error

linux 服务器程序异常崩溃退出,程序日志没有抓到堆栈信息,/var/log/message 错误如下: kernel: appname[1181]: segfault at 0000000000000018 rip 0000000000417c91 rsp 000000006b75ff20 error 4

  kernel: appname[1181]: segfault at 0000000000000018 rip 0000000000417c91 rsp 000000006b75ff20 error 4
到反汇编的信息中( objdump -d  app )查找rip 的0000000000417c91

参考资料如下  

RIP(指令指针)RIP寻址代码段存储区内的下一条指令。在64位模式中,RIP包含40位地址总线,可用于寻址1TB平展模式地址空间。
RSP(堆栈指针)RSP寻址一个称为堆栈的存储区。
error number是由三个字位组成的,从高到底分别为bit2 bit1和bit0,所以它的取值范围是0~7.
bit2: 值为1表示是用户态程序内存访问越界,值为0表示是内核态程序内存访问越界
bit1: 值为1表示是写操作导致内存访问越界,值为0表示是读操作导致内存访问越界
bit0:值为1表示没有足够的权限访问非法地址的内容,值为0表示访问的非法地址根本没有对应的页面,也就是无效地址

  内存不足不会引起段错误。段错误通常出现在访问了非法的地址后,非法地址分为3类:
1.访问的地址没有对应的物理内存。这类错误主要出现在越界访问,例如栈越界。比如说当前进程的栈只有5个页和它对应,共20k大小(x86平台),你访问的地址超过了这个范围,就会发生segmentation fault。
2.对地址的操作与该地址的属性不符合。例如该地址对应的内存是只读的,如文本段,你却试图进行写操作。
3.低权限访问高权限地址。这类情况发生在用户进程试图访问内核空间。例如x86中,TASK_SIZE以上的地址为内核空间,当用户态进程试图访问这些地址时,segmentation fault。

  readelf -s app  查看符号表 (nm 也可以查看符号表)
objdump -d  app 反汇编

  如果程序编译的时候 加参数 -g 的话(例如:gcc -g -o test test.c)通过下面可以对应到代码行
addr2line -e testseg 0000000000400470 

  readelf -s a.out 可以查看符号表,就能找到对应的函数了。
objdump -d a.out > a.s 可以反汇编,不但能找到函数,还能直接定位到指令。
http://blog.csdn.net/eroswang/archive/2007/12/25/1967243.aspx
参考资料:


http://en.wikipedia.org/wiki/Segmentation_fault
http://hi.baidu.com/sky_hacker/blog/item/86a933dcd6a858abcc116623.html
http://stackoverflow.com/questions/1456899/what-are-segfault-rip-rsp-numbers-and-how-to-use-them
http://topic.csdn.net/u/20100610/10/8e752d2e-ec9b-4f4e-8c30-fb02f2a77c60.html

 

发表评论

电子邮件地址不会被公开。 必填项已用 * 标注

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>