首页 > 解决方案 > 有没有办法确定程序是否将 -ggdb 作为 gcc 选项提供?

问题描述

在我的 C++ 程序中,我使用两种类型的构建。一种是没有调试信息的优化构建(gcc -O3),另一种是带有调试信息的优化构建(gcc -ggdb -O3)。在我的程序中,我使用 dlopen ("library_name", RTLD*) 来加载一些共享库。这些共享库也有相同的两个版本。

现在我的问题是我是否可以在我的代码中找到 -ggdb 选项是否包含在构建中,以便我可以执行以下操作。

if (with_debug_info_build)//Need some way to identify whether -ggdb is provided
{
     void* h = dlopen("my_library.od.so", RTLD*);//Load library with debug info
}
else
{
      void* h = dlopen("my_library.so", RTLD*);//Load library without debug info
}

非常感谢您对此的帮助。谢谢。

标签: c++gccshared-libraries

解决方案


在我的 C++ 程序中,我使用两种类型的构建。一种是没有调试信息的优化构建(gcc -O3),另一种是带有调试信息的优化构建(gcc -ggdb -O3)。

不是您问题的直接答案,但上述设置通常是解决它试图解决的任何问题的错误方法。

相反,您应该做的是有一个用于开发和调试的单一构建,以及一种将整个安装目录复制到单独的“发布”目录并在“发布”目录中的所有二进制文件上运行的方法。-O3 -ggdbstrip -g

二进制文件应该从它们相应的安装树中加载共享库(这很容易实现,例如-Wl,-rpath='$ORIGIN/../lib',如果二进制文件是${dir}/bin/exe并且您希望它${dir}/lib用于共享库)。

优点:

  • 您可以将发布二进制文件发送到您需要的任何地方,并且仍然可以访问完全匹配的完整调试信息
  • 不要乱搞LD_LIBRARY_PATH——“正确”的库版本会自动加载

现在我的问题是我是否可以在我的代码中找到 -ggdb 选项是否包含在构建中?

是的你可以。为此,您需要解析磁盘上的可执行文件,并确定它是否具有调试信息。

这是特定于平台的。假设您有一个 ELF 文件,您可以解析其节表,查找名为 、 等的节.debug_info.debug_line。如果您添加-frecord-gcc-switches到您的编译行,您还可以阅读.GCC.command.line部分以查找使用的命令行,例如

gcc -g -O3 t.c -frecord-gcc-switches

readelf -x.GCC.command.line a.out

Hex dump of section '.GCC.command.line':
  0x00000000 2d696d75 6c746961 72636820 7838365f -imultiarch x86_
  0x00000010 36342d6c 696e7578 2d676e75 00742e63 64-linux-gnu.t.c
  0x00000020 002d6d74 756e653d 67656e65 72696300 .-mtune=generic.
  0x00000030 2d6d6172 63683d78 38362d36 34002d67 -march=x86-64.-g
  0x00000040 002d4f33 002d6672 65636f72 642d6763 .-O3.-frecord-gc
  0x00000050 632d7377 69746368 6573002d 66617379 c-switches.-fasy
  0x00000060 6e636872 6f6e6f75 732d756e 77696e64 nchronous-unwind
  0x00000070 2d746162 6c657300                   -tables.


推荐阅读