dmesg 查看
[368101.126380] ConsDisp0_0[96881]: segfault at 8 ip 00007fc5d6445680 sp 00007fc5cd41f400 error 4 in libpf_http_restore.so[7fc5d6442000+8000]
[368101.129141] Code: 8b 06 49 8b 34 24 ff 50 28 49 c7 04 24 00 00 00 00 48 83 c4 18 5b 5d 41 5c 41 5d 41 5e 31 c0 41 5f c3 0f 1f 84 00 00 00 00 00 <49> 8b 7c 24 08 e8 d6 cc ff ff bf 88 00 00 00 e8 3c cd ff ff 49 89
两行重要的信息
第一行:崩溃线程与可执行程序或库 segfault 各项含义
segfault at 8 ip 00007fc5d6445680 sp 00007fc5cd41f400 error 4 in lib_test.so[7fc5d6442000+8000]
at 引起故障的地址
ip 指令的内存地址
sp 堆栈指针地址, 即栈顶指针
error 是由三个字位组成的,从高到底分别为bit2 bit1和bit0,所以它的取值范围是0~7. 此例为4 -> 100
bit2: 值为1表示是用户态程序内存访问越界,值为0表示是内核态程序内存访问越界
bit1: 值为1表示是写操作导致内存访问越界,值为0表示是读操作导致内存访问越界
bit0: 值为1表示没有足够的权限访问非法地址的内容,值为0表示访问的非法地址根本没有对应的页面,也就是无效地址
[7fc5d6442000+8000] 对象崩溃时映射的虚拟内存起始地址和大小
此例出错在 lib_test.so 中,程序起始映射地址为7fc5d6442000, 崩溃时指令地址为 00007fc5d6445680 ,则指令的偏移地址为(00007fc5d6445680 - 7fc5d6442000 = 3680)
第二行:Code信息,崩溃前后的地址
此处为<49> 8b 7c 24 08
定位
反汇编
使用objdump命令得到 libadd.so 的反汇编信息:
objdump -S lib_test.so > libtmp
两种方式定位:
1、根据code 地址信息
根据就code <49> 8b 7c 24 08 信息,直到出现问题的地址开始为 49,则可以直接搜索 “ 49”(\t49), 搜索出的有多个满足,则需要根据49前后的地址验证来定位。
只是有可能会有较多重复的,难以定位,不推荐
2、根据segfault 信息定位
起始地址 + 偏移量 = 错误指令地址 b000 + 3680= E680
根据上述信息过滤到命令:
测试代码
此代码出错在 函数中,在本文件的第73行使用了空指针
结果分析
1、根据地址和指令分析
根据 上述的 E680 位置代码。
2、使用 addr2line
查看出错的函数和行号
如果编译时不加-g 则没有行号