segfault信息分析:segfault at a ip 00007f4220309664 sp 00007fff580042b0 error 4 in librt-2.17.so[7f422030

在编写linux程序时,程序崩溃,用dmesg查看到如下信息:

[7470411.358752] nmsrvd[10715]: segfault at a ip 00007f4220309664 sp 00007fff580042b0 error 4 in librt-2.17.so[7f4220305000+7000]

信息分析


at a :程序崩溃的内存指针变量的值,该示例的变量值为a(十进制 10),显然不是一个合法的内存地址。
ip 00007f4220309664 :指令所在的地址
sp 00007fff580042b0:当前的栈寄存器的值
error 4 :错误类型,当前示例的值为 4,表示访问违规,说明at 指向的值不是一个合法的内存地址
librt-2.17.so :崩溃所在的模块名,当前示例为动态库 /usr/lib64/librt-2.17.so
[7f4220305000+7000] 7f4220305000是librt-2.17.so在加载到内存中的起始地址(基地址),同一个程序在不同时刻启动加载的librt-2.17.so的基地址可能是不同的。

error 错误类型 的定义如下:

 * 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

当前示例的error值为 4 为二进制 100,表示:user-mode access read access, no page found, 即用户模式读访问一个不存在的内存地址,根据这个推断,肯定是访问了一个不合法的内存地址。

那么通过该信息,怎样定位到崩溃位置的函数或行号呢?

用 ip 的值 00007f4220309664 减去 基地址 7f4220305000,可以获得错误在librt-2.17.so 中的偏移指令的地址,该示例:

00007f42203096647f42203050004664 (十六进制)

linux有一个工具 addr2line命令,可以帮助定位,通过如下命令行定位:

whereis librt-2.17.so

librt-2.17: /usr/lib/librt-2.17.so /usr/lib64/librt-2.17.so

addr2line -f -C -e /usr/lib64/librt-2.17.so 4664

 shm_unlink
??:?  

可以看到,是在调用  librt-2.17.so 库函数 shm_unlink 时发生了错误,笔者查看程序源代码,果然发现有一处调用了 shm_unlink 函数,没有进行相关指针检查而导致了segfault。

你可能感兴趣的:(Linux项目编译,Linux,C++,linux,运维,segfault,at)