gdb调试定位精度以及in ??问题

本文主要讨论用gdb追寻程序错误时,gdb所能定位问题的精度,以及影响gdb调试的因素。

1. 查看一个动态库(.so文件)或者可执行文件是否是debug版本。

readelf -S libxxx.so |grep debug

如果有输出,代表是debug版本

2. g++编译时是否加了-g对后期调试的影响

以下的测试代码,源代码为testso.cpp,并且链接了一个动态库libmyso.so,动态库libmyso.so是有so.cpp编译而来。其中so.cpp有一个越界的错误,运行后报segmentfault错误。

| testso.cpp testso.h
| so.cpp so.h

testso.cpp内容

 #include <iostream>
 #include <vector>
 #include "./so.h"
 using namespace std;
 int main()
 {
    
    
       testso();
 }
  • 生成动态库,编译testso.cp 都不加 -g 参数

g++ so.cpp -fPIC -shared -o libmyso.so
g++ testso.cpp -l myso -o a.out

编译成功后,运行a.out。程序down掉生成core文件。

gdb ./a.out corefile

动态库和源代码都不加-g编译
如图,能看到调用堆栈,但不能确定哪一行

  • 生成动态库不加 -g,编译testso.cp 加 -g 参数

g++ so.cpp -fPIC -shared -o libmyso.so
g++ -g testso.cpp -l myso -o a.out

在这里插入图片描述
能定位到testso.cpp的第七行发生了错误

  • 生成动态库加 -g 参数,编译testso.cp 不加 -g 参数

g++ so.cpp -fPIC -shared -o libmyso.so
g++ -g testso.cpp -l myso -o a.out

在这里插入图片描述
so.app可以定位到行,但是testso.cpp不能定位。
从上面可以简单总结:只有加了 -g 参数,gdb调试才能精确到行,不论是动态库还是自己的源代码。

3.gdb调试显示堆栈信息为 in ??()

gdb并不是万能,很多情况下可能会出现执行bt后堆栈信息全部是 in??。目前了解到的可能原因是:

  • 程序异常退出时破坏了堆栈信息
  • 运行环境与调试环境不一致
    前一种情况,再想利用gdb进一步定位,会比较困难。可以考虑使用别的工具进行问题的定位,例如valgrind。个人在遇到此问题时,就是利用valgrind的内存分析最终找到了异常程序的崩溃问题所在。

猜你喜欢

转载自blog.csdn.net/sinat_36304757/article/details/94773048