以下段错误消息的正确解释是什么?
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]
答案 0 :(得分:82)
这是一个段错误,因为跟随空指针试图找到要运行的代码(即,在取指令期间)。
运行addr2line -e yourSegfaultingProgram 00007f9bebcca90d
(并对给定的其他指令指针值重复)以查看错误发生的位置。更好的是,获得一个调试检测的构建,并在调试器(如gdb)下重现该问题。
不幸的是,你被软管了;事后,动态链接器无法知道库在内存中的位置。重现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
*/
答案 1 :(得分:45)
错误4表示“原因是用户模式读取导致找不到页面。”。有一个解码它的工具here。
这是内核的定义。请记住,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]”告诉你:
如果您获取基地址并从ip中减去它,您将获得该对象的偏移量:
0x00007f9bebcca90d - 0x7f9beb83a000 = 0x49090D
然后你可以在它上面运行addr2line:
addr2line -e /usr/lib64/qt45/lib/libQtWebKit.so.4.5.2 -fCi 0x49090D
??
??:0
在我的情况下它没有成功,我安装的副本与你的副本不同,或者它被剥离。
答案 2 :(得分:10)
让我们去看看来源 - 2.6.32, for example。如果设置了show_unhandled_signals sysctl,则由arch / x86 / mm / fault.c中的show_signal_msg()函数打印该消息。
“error”不是errno也不是信号编号,它是“页面错误错误代码” - 请参阅enum x86_pf_error_code的定义。
“[7fa44d2f8000 + f6f000]”是崩溃时映射违规对象的虚拟内存区域的起始地址和大小。 “ip”的值应该适合这个区域。掌握了这些信息后,很容易在gdb中找到有问题的代码。