服务器上由于怕软件bug以及磁盘的限制,一般会将core文件关掉.
ulimit -a查看当前core file size设置.
这样程序有bug崩溃以后,只能通过dmesg查看有限信息.典型信息如下:
collector[1847]: segfault at 000000000000000c rip 000000000040308a rsp 0000007fbffff820 error 4
at后面地址:访问越界的地址,rip:指令地址,rsp:栈地址,error:错误类型.
error number是由三个字位组成的,从高到底分别为bit2 bit1和bit0,所以它的取值范围是0~7.
bit2: 值为1表示是用户态程序内存访问越界,值为0表示是内核态程序内存访问越界
bit1: 值为1表示是写操作导致内存访问越界,值为0表示是读操作导致内存访问越界
bit0: 值为1表示没有足够的权限访问非法地址的内容,值为0表示访问的非法地址根本没有对应的页面,也就是无效地址
一般的程序带-g编译的话用addr2line -e ./collector 000000000040308a就大概能定位到函数
想具体一点定位可能是哪行语句的话,用objdump -d ./collector查看40308a对应的程序汇编代码即可.
当然core文件能更好的帮助解决问题,最好还是在程序里用setrlimit来设置core文件,然后根据命令行参数及是否已经生成了core文件等逻辑来判断是否生成core文件.
[cloud@iotserver1 /home/s/apps/CloudSearch/robotqa/module]$ dmesg | grep robotqa
robotqa[2516]: segfault at 7f8e52237390 ip 00007f8d0cdff9c3 sp 00007f8d05c24e00 error 4 in libmod_robotqa.so.1.179819[7f8d0ca6b000+544000]
robotqa[57618]: segfault at 7f8d6b1c38a0 ip 00007f8d0cdff9c3 sp 00007f8d05c26030 error 4 in libmod_robotqa.so.1.179819[7f8d0ca6b000+544000]
robotqa[2510]: segfault at 7f8e52237390 ip 00007f8d0cdff9c3 sp 00007f8d05c24e00 error 4 in libmod_robotqa.so.1.179819[7f8d0ca6b000+544000]
You have new mail in /var/spool/mail/cloud
[cloud@iotserver1 /home/s/apps/CloudSearch/robotqa/module]$ addr2line -e libmod_robotqa.so.1.180719 3949C3 -fCi
~IndexMap
/home/jiawenjie/2.2.1/src/../trie/index_map.h:104
~NGramDict
/home/jiawenjie/2.2.1/src/../include/ngram_dict.h:88
~NerDictSet
/home/jiawenjie/2.2.1/src/ner_dict_set.cpp:69
对于.so文件的话需要用ip的地址减去so的base地址来得到函数的相应地址,上例中即00007f8d0cdff9c3 - 7f8d0ca6b000 = 3949C3
然后利用addr2line定位具体函数
stackoverflow的答案:
Now then, "ip 00007f9bebcca90d" means the instruction pointer was at 0x00007f9bebcca90d when the segfault happened.
"libQtWebKit.so.4.5.2[7f9beb83a000+f6f000]" tells you:
The object the crash was in: "libQtWebKit.so.4.5.2"
The base address of that object "7f9beb83a000"
How big that object is: "f6f000"
If you take the base address and subtract it from the ip, you get the offset into that object:
0x00007f9bebcca90d - 0x7f9beb83a000 = 0x49090D
Then you can run addr2line on it:
addr2line -e ./usr/lib64/qt45/lib/libQtWebKit.so.4.5.2 -fCi 0x49090D