没有-g选项编译的代码调用堆栈(gcc编译器)

时间:2010-11-13 14:34:59

标签: c++ c linux gcc gdb

如何分析核心转储(使用gdb) 哪个不是用-g GCC选项编译的?

3 个答案:

答案 0 :(得分:6)

生成地图文件。映射文件将告诉您每个函数的起始地址(作为从exe开头的偏移量,因此您需要知道其加载的基址)。然后,您查看指令指针并查找它在地图文件中的位置。这使您可以很好地了解给定函数中的位置。

然而,手动展开堆栈有点像黑色艺术,因为您不知道编译器执行了哪些优化。当你大致知道你在代码中的位置时,你通常可以计算堆栈上应该是什么,并扫描内存以找到返回指针。然而它非常复杂。您有效地花了很多时间读取内存数据并查找看起来像内存地址的数字,然后检查它是否符合逻辑。它是完全可行的,我,我相信很多其他人,已经做了很多次:))

答案 1 :(得分:2)

使用ELF二进制文件,可以将调试符号分隔为单独的文件。引自objcopy man pages

  1. 正常链接可执行文件(使用-g标志)。假设那被称为foo然后......
  2. 运行objcopy --only-keep-debug foo foo.dbg以创建包含调试信息的文件。
  3. 运行objcopy --strip-debug foo以创建剥离的可执行文件。
  4. 运行objcopy --add-gnu-debuglink = foo.dbg foo,将调试信息的链接添加到已剥离的可执行文件中。

答案 2 :(得分:1)

这应该不是问题,您可以使用-g选项再次编译源代码并将gdb传递给核心和新编译的调试二进制文件,它应该没有任何问题。

BTW您可以使用gcc

中的以下命令生成地图文件

gcc -Wl,-Map = system.map file.c

上面的行应该生成地图文件system.map,一旦生成了地图文件,你可以按照上面提到的那样映射地址,但我不确定你将如何映射共享库,这是非常困难的