一、 问题现象
用户环境发生段错误,提供信息如下:
Dmesg:
myTest[12427]: segfault at 845bf7c ip 6f57c612 sp 77c9f3d8 error 4in libsqlite3.so.0.8.6[6f535000+63000]
myTest[12743]: segfault at 9788f7c ip 6f550612 sp 77d9cc88 error 4 in libsqlite3.so.0.8.6[6f509000+63000]
myTest[13098]: segfault at 9ef5f7c ip 6f58b612 sp 779e77f8 error 4 in libsqlite3.so.0.8.6[6f544000+63000]
myTest[13425]: segfault at 8d5ff7c ip 6f59c612 sp 77891f08 error 4 in libsqlite3.so.0.8.6[6f555000+63000]
myTest[13732]: segfault at 8414f7c ip 6f56c612 sp 77ece3e8 error 4 in libsqlite3.so.0.8.6[6f525000+63000]
myTest[14053]: segfault at 8275f7c ip 6f62a612 sp 77d328b8 error 4 in libsqlite3.so.0.8.6[6f5e3000+63000]
myTest[14378]: segfault at 8229f7c ip 6f68c612 sp 77abb468 error 4 in libsqlite3.so.0.8.6[6f645000+63000]
myTest[14682]: segfault at 9315f7c ip 6f5c3612 sp 77fe8358 error 4 in libsqlite3.so.0.8.6[6f57c000+63000]
myTest[15009]: segfault at 99f1f7c ip 6f654612 sp 77a75248 error 4 in libsqlite3.so.0.8.6[6f60d000+63000]
myTest[15318]: segfault at 8690f7c ip 6f5f6612 sp 7799bf68 error 4 in libsqlite3.so.0.8.6[6f5af000+63000]
myTest[15621]: segfault at 8fd0f7c ip 6f624612 sp 778f78b8 error 4 in libsqlite3.so.0.8.6[6f5dd000+63000]
二、相关资料解读
段错误:
Nov 3 17:03:54 haier-45 kernel: haierUpassServe[22708]: segfault at 3946 ip 0000000000003946 sp 00007f56edf20e18 error 14 in haierUpassServer[400000+13000]
以上信息说明:
开始是系统当前时间
进程名字及pid
segfault at 引起故障的地址
ip 指令的内存地址
sp 堆栈指针地址, 及栈顶指针
err is not an errno nor a signal numbe, but page fault error code
[400000+13000] 对象崩溃时映射的虚拟内存起始地址和大小
这种信息一般都是由内存访问越界造成的,不管是用户态程序还是内核态程序访问越界都会出core, 并在系统日志里面输出一条这样的信息。这条信息的前面分别是访问越界的程序名,进程ID号,访问越界的地址以及当时进程堆栈地址等信息,比较有用的信息是 最后的error number.
在上面的例子中,error number是4, 转成二进制就是110, 即bit2=1, bit1=0, bit0=0, 按照上面的解释,我们可以得出这条信息是由于用户态程序读操作访问越界造成的。
error number是由三个字位组成的,从高到底分别为bit2 bit1和bit0,所以它的取值范围是0~7.
bit2: 值为1表示是用户态程序内存访问越界,值为0表示是内核态程序内存访问越界
bit1: 值为1表示是写操作导致内存访问越界,值为0表示是读操作导致内存访问越界
bit0: 值为1表示没有足够的权限访问非法地址的内容,值为0表示访问的非法地址根本没有对应的页面,也就是无效地址
参考连接:
https://blog.youkuaiyun.com/wangtingting_100/article/details/83749504
https://stackoverflow.com/questions/2549214/interpreting-segfault-messages
三、错误定位
myTest[12427]: segfault at 845bf7c ip 6f57c612 sp 77c9f3d8 error 4in libsqlite3.so.0.8.6[6f535000+63000]
因此,可看出,我们的程序出错在libsqlite3.so.0.8.6中,指令地址6f57c612,libsqlite3.so.0.8.6起始映射地址6f535000,计算指令的偏移地址:6f57c612 - 6f535000 = 47612。
使用objdump命令得到ibsqlite3.so.0.8.6的反汇编信息:
objdump -d /usr/lib/libsqlite3.so.0.8.6 > libtmp
/lib/libsqlite3.so.0.8.6: file format elf32-i386
Disassembly of section .init:
00009558 <_init>:
9558: 55 push %ebp
9559: 89 e5 mov %esp,%ebp
955b: 83 ec 08 sub $0x8,%esp
955e: e8 cd 23 00 00 call b930 <sqlite3_last_insert_rowid@plt+0x10>
9563: e8 78 24 00 00 call b9e0 <sqlite3_last_insert_rowid@plt+0xc0>
9568: e8 23 1f 05 00 call 5b490 <sqlite3_create_module+0x710>
956d: c9 leave
956e: c3 ret
Disassembly of section .plt:
00009570 <sqlite3_column_text@plt-0x10>:
9570: ff b3 04 00 00 00 pushl 0x4(%ebx)
9576: ff a3 08 00 00 00 jmp *0x8(%ebx)
957c: 00 00 add %al,(%eax)
...
00009580 <sqlite3_column_text@plt>:
9580: ff a3 0c 00 00 00 jmp *0xc(%ebx)
9586: 68 00 00 00 00 push $0x0
958b: e9 e0 ff ff ff jmp 9570 <_init+0x18>
.....
.....
Disassembly of section .fini:
0005b4c4 <_fini>:
5b4c4: 55 push %ebp
5b4c5: 89 e5 mov %esp,%ebp
5b4c7: 53 push %ebx
5b4c8: 83 ec 04 sub $0x4,%esp
5b4cb: e8 00 00 00 00 call 5b4d0 <_fini+0xc>
5b4d0: 5b pop %ebx
5b4d1: 81 c3 14 8f 00 00 add $0x8f14,%ebx
5b4d7: e8 84 04 fb ff call b960 <sqlite3_last_insert_rowid@plt+0x40>
5b4dc: 59 pop %ecx
5b4dd: 5b pop %ebx
5b4de: c9 leave
5b4df: c3 ret
起始地址+ 偏移量 = 错误指令地址 00009558 + 47612 = 50B6A
根据上述信息过滤到命令:
00050b60 <sqlite3VdbeSetColName>:
50b60: 55 push %ebp
50b61: 89 e5 mov %esp,%ebp
50b63: 83 ec 28 sub $0x28,%esp
50b66: 8b 4d 08 mov 0x8(%ebp),%ecx
50b69: 89 5d f4 mov %ebx,0xfffffff4(%ebp)
50b6c: 8b 55 10 mov 0x10(%ebp),%edx
50b6f: 89 7d fc mov %edi,0xfffffffc(%ebp)
50b72: bf 07 00 00 00 mov $0x7,%edi
50b77: 89 75 f8 mov %esi,0xfffffff8(%ebp)
50b7a: 8b 01 mov (%ecx),%eax
50b7c: e8 96 ae fb ff call ba17 <sqlite3_last_insert_rowid@plt+0xf7>
50b81: 81 c3 63 38 01 00 add $0x13863,%ebx
50b87: 80 78 1e 00 cmpb $0x0,0x1e(%eax)
50b8b: 75 4e jne 50bdb <sqlite3VdbeSetColName+0x7b>
50b8d: 0f af 91 f4 00 00 00 imul 0xf4(%ecx),%edx
50b94: 89 d0 mov %edx,%eax
50b96: 03 45 0c add 0xc(%ebp),%eax
50b99: 89 c2 mov %eax,%edx