Linux crash 快速定位调用栈

2019-07-13 05:20发布

一段测试代码发生非法内存访问,发生段错误收到 SIGSEGV 信号崩溃,通过如下几种方法快速的定位到崩溃前的调用栈。

1、借助 valgrind 工具。

valgrind ./test.out

可看到 test.cpp 203 行调用了 std::string 的empty 函数,导致的奔溃。0x401E2B 是函数 CDropScopeConfig::initLineContext 的地址。可通过 addr2line 查看。
addr2line -e test.out 0x401E2B -f

C++ name magling 之后的名称,可通过 c++filt 还原。

2、使用 dmesg 查看内核记录的错误信息快速的定位崩溃的地方。


非法访问 0xffffffffffffffe8 地址。地址 00000030548bc413 和源码中函数的地址差异比较大,因为这个地址的函数来自动态连接库 .so 文件中。通过 ldd 查看当前程序所动态连接的库文件,发现该地址在 /usr/lib64/libstdc++.so.6 文件的范围内,同样使用 add2line 工具,定位到具体的函数。

3、通过 core 文件快速的定位。

通过 ulimit 查看core 文件的大小配置,如果为0表示不产生 core 文件。ulimit -c unlimited 设置不限制大小。查看 /proc/sys/kernel/core_pattern 文件,查看 core 文件生成的位置。gdb test.out core文件
使用 where 打印调用栈。如果行号显示不全,推荐使用新版本的 gdb。

4、其他的 GNU 的工具集 binutils 定位。

使用 objdump 定位到对应的汇编:objdump -d /usr/lib64/libstdc++.so.6 | grep 30548bc413

objdump 得到的汇编代码定位到的位置: