首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用标准C++库调试符号?Ubuntu / Linux / libstdc++6-8-dbg?

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

Stack Overflow用户
提问于 2019-04-17 00:24:49
回答 2查看 4.7K关注 0票数 6

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

它被描述为:

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

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

代码语言:javascript
运行
复制
/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

通常用gcc编写一个(单翻译单位) C++程序,你可以写:

代码语言:javascript
运行
复制
$ g++ myprogram.cc

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

代码语言:javascript
运行
复制
$ g++ -g myprogram.cc

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

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

EN

回答 2

Stack Overflow用户

发布于 2021-06-13 07:58:05

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

但是,Ubuntu还提供了调试符号包,一旦安装,它允许GDB解析标准库中的符号,其调试符号已被删除,即在标准库的发布版本中。下面我们提供了一个如何实现的示例(我使用的是Ubuntu20.04):

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

代码语言:javascript
运行
复制
$ ldd a.out
        ...
        libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007ff8dc6f7000)
        ...

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

代码语言:javascript
运行
复制
$ dpkg -S /usr/lib/x86_64-linux-gnu/libstdc++.so.6
libstdc++6:amd64: /usr/lib/x86_64-linux-gnu/libstdc++.so.6

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

代码语言:javascript
运行
复制
$ apt list libstdc++6\*
...
libstdc++6-dbgsym/focal-updates 10.2.0-5ubuntu1~20.04 amd64
...

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

上述案文应回答任择议定书的问题。现在我就约翰的回答指出一个问题。

一旦安装了包,GDB就会自动读取调试符号。您不需要对程序进行任何不同的编译。

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

  • 调试库包:包libstdc++6-8-dbg提供带有调试符号的libstdc++库的一个版本。
  • 调试符号分页:包libstdc++6-dbgsym为libstdc++库提供调试符号。也就是说,它不包括像printf这样的函数的任何机器指令,只包含调试符号。libstdc++6-8-dbg将代码和调试符号捆绑到一个库中。
  • 发布库包:包libstdc++6-8libstdc++6提供标准库的发行版本,这意味着它们不带调试符号,只带代码。调试符号包应与发行版库一起使用。

GDB将自动读取调试符号包中的调试符号,但不会在调试库中读取。John图中的auto-load简单地指出,在加载调试库时,auto-load脚本将自动运行,与调试符号的自动加载无关。

票数 6
EN

Stack Overflow用户

发布于 2019-04-17 00:54:51

一旦安装了包,GDB就会自动读取调试符号。您不需要对程序进行任何不同的编译。

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

代码语言:javascript
运行
复制
$ 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)
        ...

或永久的:

代码语言:javascript
运行
复制
$ 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)
        ...

或者你可以把它变成一个全系统的变化。您可以在Ubuntu中通过向/etc/ld.so.conf.d/添加一个配置条目并运行ldconfig来更新缓存来做到这一点。

代码语言:javascript
运行
复制
$ 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)
        ...

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

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55718257

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档