扩展阅读:GDB为什么同时使用.symtab和DWARF

GDB 使用 .symtab 吗?

是的,它使用,而且是作为非常基础的依赖数据在使用。

为什么使用 .symtab

.symtab (符号表) 是 ELF (可执行和可链接格式) 文件的一个核心组成部分。它包含以下信息:

  • 函数名: 程序中函数的名称。这对于单步调试、设置断点和理解程序执行流程至关重要。
  • 变量名: 全局和静态变量的名称。虽然 GDB 可以 访问局部变量的信息(稍后会讲到),但 .symtab 提供了全局可访问变量的名称。
  • 符号地址: 函数和变量在内存中的地址。这对于 GDB 在调试时定位它们是必需的。
  • 节信息: 链接到包含代码和数据的 ELF 文件节的链接。

从历史上看,.symtab 是主要的调试信息来源。早期的调试器,包括最初的 GDB,都是围绕它构建的。它是一个相对简单且紧凑的数据结构。如果没有它,GDB 会受到严重限制——它无法有意义地表示程序的结构。

为什么不只用 DWARF 呢?

这是关键问题,答案是:GDB 确实 使用 DWARF 信息,但它并没有 取代 .symtab。它们扮演着不同的、互补的角色。

让我们了解一下 DWARF:

  • 什么是 DWARF? DWARF (Debugging With Attributed Record Format) 是一种标准化的调试信息格式。它比 .symtab 更加全面。它包含:

    • 局部变量信息: 这是相对于 .symtab 的一个 主要 优势。.symtab 通常不存储函数内部的局部变量信息。
    • 类型信息: 关于变量和函数参数的数据类型细节。
    • 行号信息: 机器指令和源代码行之间的映射关系。这使得 GDB 能够显示你单步执行时对应的源代码行。
    • 参数信息: 函数参数的信息。
    • 内联函数信息: 关于内联函数的细节。
  • 为什么不能 仅仅 用 DWARF?

    • 大小和性能: DWARF 信息会显著增加可执行文件或共享库的大小。这会影响磁盘空间、内存使用以及潜在的加载时间。虽然存在压缩技术,但仍然是一个需要考虑的因素。
    • 兼容性: 虽然 DWARF 是标准化的,但存在不同的版本和扩展。较旧的 GDB 版本可能无法完全支持所有 DWARF 功能。.symtab 是一个更通用的基础。
    • 符号名称: 虽然 DWARF 可以 包含符号名称,但它通常不是存储它们的唯一地方。.symtab 仍然是可靠的函数和全局变量名称来源。有时,DWARF 可能会包含混杂或不易读懂的名称。
    • 历史原因和兼容性: GDB 的核心架构是围绕 .symtab 构建的。虽然它已经发展到高度依赖 DWARF,但完全放弃 .symtab 将是一个巨大的工程,并且会破坏与旧二进制文件的兼容性。

### GDB如何同时使用二者

这里解释下GDB 如何同时使用两者:

  1. 初始加载: GDB 首先使用 .symtab 获取基本的符号信息(函数名、地址)。
  2. 使用 DWARF 补充: 然后,它使用 DWARF 获取更详细的调试信息(局部变量、类型、行号)。
  3. 结合使用: 例如,当你单步执行时,GDB 使用 .symtab 找到函数地址,然后使用 DWARF 显示对应的源代码行。

现代 GDB 和 DWARF:

现代版本的 GDB(尤其是使用最新编译器编译的版本)高度依赖 DWARF。它提供的更丰富的调试信息显著改善了用户体验。但是,.symtab 仍然是一个关键的后备方案和基础元素。 很难想象 GDB 会在不久的将来完全放弃它。

总结:

特性 .symtab DWARF
主要用途 基本符号信息(函数名、地址) 详细的调试信息(局部变量、类型、行号)
大小 较小 较大
兼容性 非常高 取决于版本
局部变量
类型信息 有限 丰富

希望这个详细的解释能让读者更清楚地了解 GDB、.symtab 和 DWARF 之间的关系。

results matching ""

    No results matching ""