Menu Close
Red Hat Training
A Red Hat training course is available for RHEL 8
第 7 章 使用调试信息启用调试
要调试应用程序和库,需要调试信息。以下小节描述了如何获取这些信息。
7.1. 调试信息
在调试任何可执行代码时,两种类型的信息允许这些工具来比较二进制代码,进而进而是使用管理的二进制代码:
- 源代码文本
- 有关源代码文本与二进制代码的关系的描述
这些信息被称为调试信息。
Red Hat Enterprise Linux 使用 ELF 格式用于可执行二进制文件、共享库或 debuginfo
文件。在这些 ELF 文件中,DWARF 格式用于保存调试信息。
要显示保存在 ELF 文件中的 DWARF 信息,请运行 readelf -w file
命令。
STABS 是一个较老的、功能更低的格式,偶尔与 UNIX 一起使用。红帽不建议使用它。GCC 和 GDB 仅尽力提供 STABS 生产与消耗。其它工具,如 Valgrind 和 elfutils
无法用于 STABS。
其它资源
7.2. 使用 GCC 启用 C 和 C++ 应用程序调试
由于调试信息较大,默认情况下不包含在可执行文件中。要启用 C 和 C++ 应用程序调试,您必须明确指示编译器创建它。
要在编译和链接代码时使用 GCC 创建调试信息,请使用 -g
选项:
$ gcc ... -g ...
-
由编译器和链接器执行的优化可执行代码,与原始源代码很难执行:变量可能会优化、循环未滚动,操作合并到相邻的源代码等。这会影响调试。要改进的调试体验,请考虑使用
-Og
选项设置优化功能。但是,更改优化级别会更改可执行代码,并可能会更改实际行为,包括删除一些程序错误。 -
要在调试信息中包含宏定义,请使用
-g3
选项而不是-g
。 -
-fcompare-debug
GCC 选项测试由 GCC 编译的带有调试信息且没有调试信息的代码。如果得到的两个二进制文件相同,测试会传递。此测试可确保可执行代码不受任何调试选项的影响,这可以进一步确保 debug 代码中没有隐藏的错误。请注意,使用-fcompare-debug
选项会显著增加编译时间。有关这个选项的详情,请查看 GCC 手册页。
其它资源
- 第 7 章 使用调试信息启用调试
- 使用 GNU Compiler Collection(GCC)- 调试您的选项
- 使用 GDB 进行 调试 - 在 Separate 文件中调试信息
GCC 手册页:
$ man gcc
7.3. debuginfo 和 debugsource 软件包
debuginfo
和 debugsource
软件包包含程序库的调试信息和调试源代码。对于 Red Hat Enterprise Linux 软件仓库中安装的应用程序和库,您可以从附加频道获取单独的 debuginfo
和 debugsource
软件包。
调试信息软件包类型
可用于调试的软件包有两种:
- debuginfo 软件包
-
debuginfo
软件包提供了为二进制代码功能提供人类可读名称所需的调试信息。这些软件包包含包含 DWARF 调试信息的.debug
文件。这些文件安装到/usr/lib/debug
目录中。 - Debugsource 软件包
-
debugsource
软件包包含用于编译二进制代码的源文件。安装对应的debuginfo
和debugsource
软件包后,如 GDB 或 LLDB 等调试程序可以将二进制代码的执行与源代码相关联。源代码文件安装到/usr/src/debug
目录中。
RHEL 7 的不同
在 Red Hat Enterprise Linux 7 中, debuginfo
软件包包含两种信息。Red Hat Enterprise Linux 8 将从 debuginfo
软件包中调试所需的源代码数据分成独立的 debugsource
软件包。
软件包名称
debuginfo
或 debugsource
软件包只针对具有相同名称、版本、发行和架构的二进制软件包提供有效的调试信息:
-
二进制软件包:
packagename-version-release.architecture.rpm
-
debuginfo 软件包:
packagename-debuginfo-version-release.architecture.rpm
-
Debugsource 软件包:
packagename-debugsource-version-release.architecture.rpm
7.4. 使用 GDB 为应用程序或库获取 debuginfo 软件包
调试代码需要调试信息。对于从软件包中安装的代码,GDB 会自动识别缺少的调试信息,解析软件包名称并为如何获得软件包提供具体建议。
先决条件
- 您要调试的应用程序或库必须安装在系统中。
-
必须在系统中安装 GDB 和
debuginfo-install
工具。 -
在系统中必须配置并启用提供
debuginfo
和debugsource
软件包的频道。
流程
启动附加到应用程序或您要调试的程序库的 GDB。GDB 自动识别缺少调试信息并建议运行命令。
$ gdb -q /bin/ls Reading symbols from /bin/ls...Reading symbols from .gnu_debugdata for /usr/bin/ls...(no debugging symbols found)...done. (no debugging symbols found)...done. Missing separate debuginfos, use: dnf debuginfo-install coreutils-8.30-6.el8.x86_64 (gdb)
退出 GDB:输入 q 并确认 Enter。
(gdb) q
运行 GDB 建议的命令来安装所需的
debuginfo
软件包:# dnf debuginfo-install coreutils-8.30-6.el8.x86_64
dnf
软件包管理工具提供更改概述,要求确认,并在确认、下载和安装所有必要的文件后请求确认。-
如果 GDB 无法建议
debuginfo
软件包,请按照 第 7.5 节 “手动为应用程序或库获取 debuginfo 软件包” 中描述的步骤操作。
7.5. 手动为应用程序或库获取 debuginfo 软件包
您可以通过找到可执行文件,然后查找安装该文件的软件包来手动确定您需要安装哪些 debuginfo
软件包。
红帽建议您 使用 GDB 来决定安装的软件包。只有在 GDB 无法建议安装软件包时使用这个手动步骤。
先决条件
- 该应用程序或库必须安装在系统中。
- 应用程序或库是从软件包中安装的。
-
debuginfo-install
工具必须在系统中可用。 -
必须在系统中配置并启用提供
debuginfo
软件包的频道。
流程
查找应用程序或库的可执行文件。
使用
which
命令查找应用程序文件。$ which less /usr/bin/less
使用
locate
命令查找库文件。$ locate libz | grep so /usr/lib64/libz.so.1 /usr/lib64/libz.so.1.2.11
如果调试的原始原因包括错误消息,请选择库的文件名中具有与错误消息中所述相同附加号码的结果。如果有疑问,请按照其余部分步骤进行尝试,从而使库文件名称不包含额外的数字。
注意locate
命令由mlocate
软件包提供。安装并启用使用:# yum install mlocate # updatedb
搜索提供文件的软件包的名称和版本:
$ rpm -qf /usr/lib64/libz.so.1.2.7 zlib-1.2.11-10.el8.x86_64
输出提供了 名称 为epoch-version. release.架构 格式的软件包详情。
重要如果这个步骤没有生成任何结果,则无法决定哪个软件包提供了二进制文件。可能会有几个可能的情况:
- 该文件从 当前 配置中未知软件包管理工具的软件包中安装。
-
该文件从本地下载并手动安装的软件包安装。在这种情况下,无法自动决定合适的
debuginfo
软件包。 - 软件包管理工具被错误配置。
-
该文件不会从任何软件包安装。在这种情况下,不存在对应的
debuginfo
软件包。
由于进一步的步骤取决于这种情况,您必须解决这种情况,或者中止这个过程。描述准确的故障排除步骤超出了此过程的范围。
使用
debuginfo-install
工具安装debuginfo
软件包。在命令中,使用在上一步中决定的软件包名称和其他详情:# debuginfo-install zlib-1.2.11-10.el8.x86_64