段错误排查 —— 利用dmesg

本文详细解析了系统日志中的段错误信息,通过分析错误代码和内存地址,定位到具体库文件libsqlite3.so.0.8.6中的错误位置,并使用objdump命令反汇编确定了出错的具体指令。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、 问题现象

用户环境发生段错误,提供信息如下:

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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值