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.3. debuginfo 和 debugsource 软件包

debuginfodebugsource 软件包包含程序库的调试信息和调试源代码。对于 Red Hat Enterprise Linux 软件仓库中安装的应用程序和库,您可以从附加频道获取单独的 debuginfodebugsource 软件包。

调试信息软件包类型

可用于调试的软件包有两种:

debuginfo 软件包
debuginfo 软件包提供了为二进制代码功能提供人类可读名称所需的调试信息。这些软件包包含包含 DWARF 调试信息的 .debug 文件。这些文件安装到 /usr/lib/debug 目录中。
Debugsource 软件包
debugsource 软件包包含用于编译二进制代码的源文件。安装对应的 debuginfodebugsource 软件包后,如 GDB 或 LLDB 等调试程序可以将二进制代码的执行与源代码相关联。源代码文件安装到 /usr/src/debug 目录中。

RHEL 7 的不同

在 Red Hat Enterprise Linux 7 中, debuginfo 软件包包含两种信息。Red Hat Enterprise Linux 8 将从 debuginfo 软件包中调试所需的源代码数据分成独立的 debugsource 软件包。

软件包名称

debuginfodebugsource 软件包只针对具有相同名称、版本、发行和架构的二进制软件包提供有效的调试信息:

  • 二进制软件包: packagename-version-release.architecture.rpm
  • debuginfo 软件包: packagename-debuginfo-version-release.architecture.rpm
  • Debugsource 软件包: packagename-debugsource-version-release.architecture.rpm

7.4. 使用 GDB 为应用程序或库获取 debuginfo 软件包

调试代码需要调试信息。对于从软件包中安装的代码,GDB 会自动识别缺少的调试信息,解析软件包名称并为如何获得软件包提供具体建议。

先决条件

流程

  1. 启动附加到应用程序或您要调试的程序库的 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)
  2. 退出 GDB:输入 q 并确认 Enter

    (gdb) q
  3. 运行 GDB 建议的命令来安装所需的 debuginfo 软件包:

    # dnf debuginfo-install coreutils-8.30-6.el8.x86_64

    dnf 软件包管理工具提供更改概述,要求确认,并在确认、下载和安装所有必要的文件后请求确认。

  4. 如果 GDB 无法建议 debuginfo 软件包,请按照 第 7.5 节 “手动为应用程序或库获取 debuginfo 软件包” 中描述的步骤操作。

7.5. 手动为应用程序或库获取 debuginfo 软件包

您可以通过找到可执行文件,然后查找安装该文件的软件包来手动确定您需要安装哪些 debuginfo 软件包。

注意

红帽建议您 使用 GDB 来决定安装的软件包。只有在 GDB 无法建议安装软件包时使用这个手动步骤。

先决条件

流程

  1. 查找应用程序或库的可执行文件。

    1. 使用 which 命令查找应用程序文件。

      $ which less
      /usr/bin/less
    2. 使用 locate 命令查找库文件。

      $ locate libz | grep so
      /usr/lib64/libz.so.1
      /usr/lib64/libz.so.1.2.11

      如果调试的原始原因包括错误消息,请选择库的文件名中具有与错误消息中所述相同附加号码的结果。如果有疑问,请按照其余部分步骤进行尝试,从而使库文件名称不包含额外的数字。

      注意

      locate 命令由 mlocate 软件包提供。安装并启用使用:

      # yum install mlocate
      # updatedb
  2. 搜索提供文件的软件包的名称和版本:

    $ rpm -qf /usr/lib64/libz.so.1.2.7
    zlib-1.2.11-10.el8.x86_64

    输出提供了 名称epoch-version. release.架构 格式的软件包详情。

    重要

    如果这个步骤没有生成任何结果,则无法决定哪个软件包提供了二进制文件。可能会有几个可能的情况:

    • 该文件从 当前 配置中未知软件包管理工具的软件包中安装。
    • 该文件从本地下载并手动安装的软件包安装。在这种情况下,无法自动决定合适的 debuginfo 软件包。
    • 软件包管理工具被错误配置。
    • 该文件不会从任何软件包安装。在这种情况下,不存在对应的 debuginfo 软件包。

    由于进一步的步骤取决于这种情况,您必须解决这种情况,或者中止这个过程。描述准确的故障排除步骤超出了此过程的范围。

  3. 使用 debuginfo-install 工具安装 debuginfo 软件包。在命令中,使用在上一步中决定的软件包名称和其他详情:

    # debuginfo-install zlib-1.2.11-10.el8.x86_64