使用标准 C++ 库调试符号?Ubuntu/Linux/libstdc++6-8-dbg?

And*_*zos 7 c++ linux ubuntu gcc libstdc++

Ubuntu Linux 上有一个名为的软件包libstdc++6-8-dbg(撰写本文时为最新版本)。

它被描述为:

GNU 标准 C++ 库 v3(调试文件) 该软件包包含使用调试符号编译的 libstdc++ 共享库。

除其他外,它还包含以下文件:

/usr/lib/x86_64-linux-gnu/debug/libstdc++.a
/usr/lib/x86_64-linux-gnu/debug/libstdc++.so.6.0.25
/usr/lib/x86_64-linux-gnu/debug/libstdc++fs.a
Run Code Online (Sandbox Code Playgroud)

通常,要使用 gcc 编译(单个翻译单元)C++ 程序,您可以编写:

$ g++ myprogram.cc
Run Code Online (Sandbox Code Playgroud)

要添加用户代码的调试符号的生成,请传递-g

$ g++ -g myprogram.cc
Run Code Online (Sandbox Code Playgroud)

但这不包括标准库的调试版本。

您需要传递哪些额外选项g++来告诉它使用 提供的标准库的调试版本libstdc++6-8-dbg

小智 6

OP 希望正确解析回溯中的 C++ 标准库符号。约翰的回答正确地指出,这可以通过链接标准库的调试版本来实现。

然而,Ubuntu 还提供了调试符号包,一旦安装,GDB 就可以解析标准库中调试符号已被删除的符号,即标准库的发行版本中的符号。我们在下面提供了一个操作示例(我使用的是 Ubuntu 20.04):

假设生成的二进制文件名为 a.out。我们首先找到它链接的 libstdc++ 版本:

$ ldd a.out
        ...
        libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007ff8dc6f7000)
        ...
Run Code Online (Sandbox Code Playgroud)

我们搜索提供共享库文件的包(/lib是到/usr/lib的符号链接。这里必须使用完整路径。):

$ dpkg -S /usr/lib/x86_64-linux-gnu/libstdc++.so.6
libstdc++6:amd64: /usr/lib/x86_64-linux-gnu/libstdc++.so.6
Run Code Online (Sandbox Code Playgroud)

按照说明添加调试符号包的存储库,然后更新包索引。该链接还描述了如何搜索调试符号包,但我直接使用包名称进行搜索:

$ apt list libstdc++6\*
...
libstdc++6-dbgsym/focal-updates 10.2.0-5ubuntu1~20.04 amd64
...
Run Code Online (Sandbox Code Playgroud)

将会有大量的结果,但一定要注意dbgsym, 而不是dbg!安装后libstdc++6-dbgsym,GDB 应该能够解析符号,即使您的二进制文件没有链接到调试库。


上面的文字应该回答OP的问题。现在我指出约翰的回答的一个问题。

安装包后,GDB 会自动读取调试符号。您不需要以任何不同的方式编译您的程序。

这个说法是100%正确的,但是所包含的数字是无关紧要的,并不能证明这个说法。这里有三个密切相关的概念:

  • 调试库包:该包libstdc++6-8-dbg提供了带有调试符号的 libstdc++ 库版本。
  • 调试符号pagkage:该包libstdc++6-dbgsym提供libstdc++库的调试符号。也就是说,它不包含诸如 之类的函数的任何机器指令printf,仅包含调试符号。libstdc++6-8-dbg将代码和调试符号捆绑到一个库中。
  • 发布库包:这些包libstdc++6-8提供libstdc++6标准库的发布版本,这意味着它们不携带调试符号,仅携带代码。调试符号包应与发布库一起使用。

GDB会自动读取调试符号包中的调试符号,但不会读取调试库中的调试符号。John 的图auto-load中只是简单地说明了Python 脚本/usr/share/gdb/auto-load/usr/lib/x86_64-linux-gnu/debug/libstdc++.so.6.0.25-gdb.py 将在以下情况下自动运行:调试库已加载,与调试符号的自动加载无关。


Joh*_*ica 3

安装包后,GDB 会自动读取调试符号。您不需要以任何不同的方式编译您的程序。

如果您希望程序加载调试版本,最好的选择是调整库搜索路径。您可以通过LD_LIBRARY_PATH临时设置来做到这一点:

$ LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu/debug/
$ ldd test
        libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/debug/libstdc++.so.6 (0x00007efcef670000)
        ...
Run Code Online (Sandbox Code Playgroud)

或永久:

$ export LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu/debug/
$ ldd test
        libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/debug/libstdc++.so.6 (0x00007efcef670000)
        ...
Run Code Online (Sandbox Code Playgroud)

或者您可以将其作为系统范围的更改。您可以在 Ubuntu 中通过添加配置条目/etc/ld.so.conf.d/并运行ldconfig以更新缓存来做到这一点。

$ sudoedit /etc/ld.so.conf.d/debug.conf
$ cat /etc/ld.so.conf.d/debug.conf
/usr/lib/x86_64-linux-gnu/debug
$ sudo ldconfig
$ ldd test
        libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/debug/libstdc++.so.6 (0x00007f3aced53000)
        ...
Run Code Online (Sandbox Code Playgroud)

配置文件按字母顺序搜索,因此只需确保您编写的文件(debug.conf上面)早于默认文件(x86_64-linux-gnu.conf在我的系统上)。