解释段错误消息
以下段错误消息的正确解释是什么?
segfault at 10 ip 00007f9bebcca90d sp 00007fffb62705f0 error 4 in libQtWebKit.so.4.5.2[7f9beb83a000+f6f000] segfault at 10 ip 00007fa44d78890d sp 00007fff43f6b720 error 4 in libQtWebKit.so.4.5.2[7fa44d2f8000+f6f000] segfault at 11 ip 00007f2b0022acee sp 00007fff368ea610 error 4 in libQtWebKit.so.4.5.2[7f2aff9f7000+f6f000] segfault at 11 ip 00007f24b21adcee sp 00007fff7379ded0 error 4 in libQtWebKit.so.4.5.2[7f24b197a000+f6f000]
这是一个段错误,因为下面的空指针试图find要运行的代码(即在取指令期间)。
如果这是一个程序,而不是共享库
运行addr2line -e yourSegfaultingProgram 00007f9bebcca90d
(并重复给出的其他指令指针值)以查看错误发生的位置。 更好的办法是获得一个debug-instrumented的构build,并在像gdb这样的debugging器下重现问题。
由于它是一个共享库
不幸的是, 事后不可能知道dynamic链接器将库放在内存中的什么位置。 在gdb
下重现问题。
错误意味着什么
以下是这些字段的细目:
-
address
(在at
) – 代码尝试访问的内存中的位置(很可能10
和11
是来自指针的偏移量,我们希望将其设置为有效值,但指向0
) -
ip
– 指令指针,即。 正在尝试这样做的代码在哪里生活 -
sp
– 堆栈指针 -
error
– 页面错误的错误代码; 请参阅下面的内容以了解x86上的含义。/* * Page fault error code bits: * * bit 0 == 0: no page found 1: protection fault * bit 1 == 0: read access 1: write access * bit 2 == 0: kernel-mode access 1: user-mode access * bit 3 == 1: use of reserved bit detected * bit 4 == 1: fault was an instruction fetch */
错误4的意思是“原因是用户模式读取导致没有find页面”。 有一个工具在这里解码。
这是来自内核的定义。 请记住,4意味着位2被设置,并且没有其他位被设置。 如果你把它转换成二进制,变得清晰。
/* * Page fault error code bits * bit 0 == 0 means no page found, 1 means protection fault * bit 1 == 0 means read, 1 means write * bit 2 == 0 means kernel, 1 means user-mode * bit 3 == 1 means use of reserved bit detected * bit 4 == 1 means fault was an instruction fetch */ #define PF_PROT (1<<0) #define PF_WRITE (1<<1) #define PF_USER (1<<2) #define PF_RSVD (1<<3) #define PF_INSTR (1<<4)
然后,“ip 00007f9bebcca90d”表示发生段错误时,指令指针位于0x00007f9bebcca90d处。
“libQtWebKit.so.4.5.2 [7f9beb83a000 + f6f000]”告诉你:
- 崩溃的对象是:“libQtWebKit.so.4.5.2”
- 该对象的基地址“7f9beb83a000”
- 这个对象有多大:“f6f000”
如果你把基地址从ip中减去,你得到了该对象的偏移量:
0x00007f9bebcca90d - 0x7f9beb83a000 = 0x49090D
然后你可以在其上运行addr2line:
addr2line -e /usr/lib64/qt45/lib/libQtWebKit.so.4.5.2 -fCi 0x49090D ?? ??:0
在我的情况下,这是不成功的,要么我安装的副本是不相同的,或者它被剥夺。
例如,让我们来看2.6.32的源代码。 如果设置了show_unhandled_signals sysctl,则消息将通过arch / x86 / mm / fault.c中的show_signal_msg()函数进行打印。
“错误”不是一个错误,也不是一个信号编号,它是一个“页错误错误代码” – 请参阅enum x86_pf_error_code的定义。
“[7fa44d2f8000 + f6f000]”是在发生崩溃时所在的虚拟内存区域的起始地址和虚拟内存区域的大小。 “ip”的值应该适合这个地区。 有了这个信息,应该很容易在gdb中find有问题的代码。