没有core文件定位bug的可能位置
2013-11-25 17:08
253 查看
有时写c/c++程序,运行后出现core, 如果有core文件则可以gdb方便的定位问题,
可是,当core文件找不到(或被删除)时如何定位?
刚做了个测试,在没有core文件的情况下对程序bug进行定位
cat core.cpp
1 #include <iostream>
2
3 int main(int argc, char** argv){
4
5 int *p = NULL;
6 for(int i=0; i<15; i++){
7 p[i] = i;
8 }
9
10 return 0;
11 }
g++ -g core.cpp -o core
./core
Segmentation fault
/var/log]# vim messages
Nov 24 04:02:08 i237 syslogd 1.4.1: restart.
Nov 25 13:55:01 i237 kernel: testreg[19978]: segfault at 000000000000000a rip 00000036ed078d50 rsp 00007fffa7125888 error 4
Nov 25 13:58:20 i237 kernel: testreg[20711]: segfault at 00000000000003e8 rip 00000036ed078d70 rsp 00007fff8e28ac98 error 4
Nov 25 16:19:10 i237 kernel: core[17962]: segfault at 0000000000000000 rip
0000000000400677 rsp 00007fff0c53dc30 error 6
最后一个core[17962]即是刚才生成core的进程
可以到这个core.cpp生成core的目录下
执行:
addr2line 0000000000400677 -e /path/./core
输出:
....../core.cpp:7
这样我们可以初步定位到位core.cpp第7行的问题,回到程序中看是非法地址的赋值
我们看下man addr2line
NAME
addr2line - convert addresses into file names and line numbers.
这个命令本身就是把地址转成名称和行号的,只是我们对于这个地址需要在message日志中看rip地址才能得到
另外,error 后的数字转换到二进制依次对应描述如下:
bit2: 值为1表示是用户态程序内存访问越界,值为0表示是内核态程序内存访问越界
bit1: 值为1表示是写操作导致内存访问越界,值为0表示是读操作导致内存访问越界
bit0: 值为1表示没有足够的权限访问非法地址的内容,值为0表示访问的非法地址根本没有对应的页面,也就是无效地址
所以从这个error 6也可以知道原因是 用户程序操作访问越界
最后百科里借用一个寄存器:
专用寄存器
专用寄存器包括: RIP、RSP和RFLAGS以及段寄存器CS、DS、ES、SS、FS和GS。
RIP(指令指针)RIP寻址代码段存储区内的下一条指令。当微处理器工作在实模式下时,这个寄存器是IP(16位);当80386及更高型号的微处理器工作于保护模式下时,则是EIP(32位)。注意,8086、8088和80286不包含EIP寄存器,而且只有80286及更高型号的微处理器可以工作于保护模式。指令指针指向程序的下一条指令,用于微处理器在程序中顺序地寻址代码段内的下一条指令。指令指针也可由转移指令或调用指令修改。在64位模式中,RIP包含40位地址总线,可用于寻址1TB平展模式地址空间。
RSP(堆栈指针)RSP寻址一个称为堆栈的存储区。通过这个指针存取堆栈存储器数据,具体操作将在本书后面讲解访问堆栈存储器数据的指令时再进行说明。这个寄存器作为16位寄存器被引用时,为SP;如果作为32位寄存器,则是ESP。
可是,当core文件找不到(或被删除)时如何定位?
刚做了个测试,在没有core文件的情况下对程序bug进行定位
cat core.cpp
1 #include <iostream>
2
3 int main(int argc, char** argv){
4
5 int *p = NULL;
6 for(int i=0; i<15; i++){
7 p[i] = i;
8 }
9
10 return 0;
11 }
g++ -g core.cpp -o core
./core
Segmentation fault
/var/log]# vim messages
Nov 24 04:02:08 i237 syslogd 1.4.1: restart.
Nov 25 13:55:01 i237 kernel: testreg[19978]: segfault at 000000000000000a rip 00000036ed078d50 rsp 00007fffa7125888 error 4
Nov 25 13:58:20 i237 kernel: testreg[20711]: segfault at 00000000000003e8 rip 00000036ed078d70 rsp 00007fff8e28ac98 error 4
Nov 25 16:19:10 i237 kernel: core[17962]: segfault at 0000000000000000 rip
0000000000400677 rsp 00007fff0c53dc30 error 6
最后一个core[17962]即是刚才生成core的进程
可以到这个core.cpp生成core的目录下
执行:
addr2line 0000000000400677 -e /path/./core
输出:
....../core.cpp:7
这样我们可以初步定位到位core.cpp第7行的问题,回到程序中看是非法地址的赋值
我们看下man addr2line
NAME
addr2line - convert addresses into file names and line numbers.
这个命令本身就是把地址转成名称和行号的,只是我们对于这个地址需要在message日志中看rip地址才能得到
另外,error 后的数字转换到二进制依次对应描述如下:
bit2: 值为1表示是用户态程序内存访问越界,值为0表示是内核态程序内存访问越界
bit1: 值为1表示是写操作导致内存访问越界,值为0表示是读操作导致内存访问越界
bit0: 值为1表示没有足够的权限访问非法地址的内容,值为0表示访问的非法地址根本没有对应的页面,也就是无效地址
所以从这个error 6也可以知道原因是 用户程序操作访问越界
最后百科里借用一个寄存器:
专用寄存器
专用寄存器包括: RIP、RSP和RFLAGS以及段寄存器CS、DS、ES、SS、FS和GS。
RIP(指令指针)RIP寻址代码段存储区内的下一条指令。当微处理器工作在实模式下时,这个寄存器是IP(16位);当80386及更高型号的微处理器工作于保护模式下时,则是EIP(32位)。注意,8086、8088和80286不包含EIP寄存器,而且只有80286及更高型号的微处理器可以工作于保护模式。指令指针指向程序的下一条指令,用于微处理器在程序中顺序地寻址代码段内的下一条指令。指令指针也可由转移指令或调用指令修改。在64位模式中,RIP包含40位地址总线,可用于寻址1TB平展模式地址空间。
RSP(堆栈指针)RSP寻址一个称为堆栈的存储区。通过这个指针存取堆栈存储器数据,具体操作将在本书后面讲解访问堆栈存储器数据的指令时再进行说明。这个寄存器作为16位寄存器被引用时,为SP;如果作为32位寄存器,则是ESP。
相关文章推荐
- 再聊用strace来定位没有core文件的core dump
- 如何利用core文件定位bug.
- linux中的dmesg命令简介------没有core文件时如何定位core dump问题
- 无core文件时应用addr2line定位死机位置
- 再聊没有core文件时候如何定位segment/core dump
- fread返回0或者不是期望的值,那么是否会读取到数据(如果数据没有读完的话),并改变了文件的指针位置?
- spring定位配置文件位置开启spring.
- 定位的一个yaffs2文件系统的bug
- Windows无法访问指定设备,路径或文件.您可能没有合适的权限访问这个项目
- 以前听师傅说, 某同学某变量没有初始化, 结果定位3-4天才解决bug
- xcode4.2 模拟器定位 。xcode4.2 添加GPX文件。手工指定位置。
- php如何实现不借助IDE快速定位行数或者方法定义的文件和位置
- 完美解决“windows 无法访问指定设备、路径或文件。你可能没有合适的权限访问这个项目”
- 利用.dSYM和.app文件准确定位Crash位置
- GDB调试core文件样例(如何定位Segment fault)
- iOS定位 - 普通定位(没有地图) - 反地理编码(得到具体位置)
- Visual Studio环境下生成dump文件及利用dump文件定位程序出错位置
- CUDA 在 suse10.3下面的安装 (自己的安装过程,没有对其他的想法或可能存在的bug进行测试)
- Linux下打开core文件,定位segfault
- VMware Tools"无法计算本地文件大小。你可能没有执行该操作的权限。”的解决方法