c - 如何从 clang 获取更细粒度的行/列调试信息?

标签 c debugging compiler-construction clang dwarf

我正在编写软件,对其他程序进行一些相当复杂的静态分析和动态跟踪。该程序使用大量静态 DWARF 信息来协助跟踪,包括来自 .debug_line 的行/列信息。矮人节。为了使该程序具有我们需要的准确性,它必须具有细粒度且准确的行号和列号信息,以填充到 DWARF 调试信息中。使用 clang我可以使用 -g -Xclang -dwarf-column-info 强制填充行和列信息选项一起。

但是,在某些情况下,clang 不会生成足够细粒度的列信息。一个特定的例子是 for循环。采用以下示例程序,我将其称为 source01.c :

  1      
  2 int main ()
  3 {    
  4     int number1 = 10, number2 = 20;
  5     for (int i=0; i < 10; ++i) {                                                                                                                           
  6         number1++;
  7         number2++;
  8     }
  9     return 0;
 10 } 

我可以这样编译它:

clang -g -Xclang -dwarf-column-info source01.c

生成可执行文件 a.out .然后我使用 dwarfdump检查行/列信息的填充方式:

dwarfdump a.out > dwarf_info

看看 .debug_line部分,我看到此可执行文件的调试信息中包含的所有行/列对:

.debug_line: line number info for a single cu
Source lines (from CU-DIE at .debug_info offset 0x0000000b):

<pc>        [row,col] NS BB ET PE EB IS= DI= uri: "filepath"
NS new statement, BB new basic block, ET end of text sequence
PE prologue end, EB epilogue begin
IA=val ISA number, DI=val discriminator value
0x004004f0  [   3, 0] NS uri: "/xxx/loop_01/source01.c"
0x004004fb  [   4, 5] NS PE
0x00400509  [   5,10] NS
0x0040051d  [   6, 9] NS
0x00400528  [   7, 9] NS
0x00400533  [   5,27] NS
0x00400548  [   9, 5] NS
0x0040054a  [   9, 5] NS ET

如您所见,有一对 (5,10),它对应于 int i=0; , 和 (5,27) 对,对应于 ++i .但是,我希望(并且需要)还有一对 (5,19),它对应于 i < 10。 ,但它不存在。我已经用 objdump 检查了可执行文件的指令, 并确认确实有指令对应于比较 i < 10 (因此,它并没有被简单地“优化掉”)。

您是否知道为什么 clang 不会填充此信息?或者有没有办法强制clang生成更细粒度的列信息?好像clang应该有这个能力,因为 clang 的 AST生成器在其自身与源代码行和列之间具有极其细粒度的映射。

谢谢。

最佳答案

这与其说是一个借口,不如说是一个真正的解决方案,但是......

我相信第一个条目 (5, 8) 包括 for 循环中的初始化程序和条件语句的代码。当我使用 for 循环编译程序时,这两个语句最终出现在连续的地址范围内。

强制 clang 为每个语句生成一个单独的条目会很好,但我似乎找不到任何可以做到这一点的东西。

关于c - 如何从 clang 获取更细粒度的行/列调试信息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22871047/

相关文章:

c - 结构体的动态内存分配,但它的 int 或 double 成员呢

c - main 的 ret 指令在哪里

c - 如何在 emscripten 编译库中读取用户指定的文件?

winapi - 在 Windows 7 中成功 SuspendThread 后 GetThreadContext 失败

.NET 记录或查看 SOAP WebService 的调用/响应

c - 函数的隐式声明

c - 为什么 SIGALRM 第二次不工作?

debugging - 使用 rust-gdb 进行调试时,如何进入在返回值中调用的函数?

c++ - 分支? : operator?

java - 词法分析时如何存储token