Will Diez 描述了他是如何实现的:
https ://groups.google.com/d/msg/llvm-dev/O4Dj9FW1gtM/ovnm6dqoJJsJ
大家好,
出于我自己的目的,我写了一个完全符合你们所描述的过程:将调试元数据添加到 LLVM IR。
作为通行证,它必须解决“这个文件需要存在于磁盘上的某个地方以便 gdb 可以找到它”的问题,我解决了我将它转储到某个地方的 /tmp/ 的问题。不是一个很好的解决方案(谁删除了这些?)但效果很好。
另一个有趣的问题是如何与任何现有的调试元数据共存,这对于同时调试与 C 源代码内联的 IR 转换以用于诸如 SAFECode、ASan/TSan 之类的仪表式通行证很有用。
快速示例:
(gdb) break main
Breakpoint 1 at 0x4010b1: file
/home/wdietz2/magic/test/unit/test_loop.c, line 9.
(gdb) r
Starting program:
/home/wdietz2/llvm/32-obj-make/projects/magic/test/Output/test_loop
Breakpoint 1, main (argc=<value optimized out>, argv=<value optimized
out>) at /home/wdietz2/magic/test/unit/test_loop.c:9
9 unsigned k = 0;
Missing separate debuginfos, use: debuginfo-install
glibc-2.12-1.80.el6_3.5.x86_64 libgcc-4.4.6-4.el6.x86_64
libstdc++-4.4.6-4.el6.x86_64
(gdb) n
10 source(argc != 0, &k);
(gdb) n
14 %and.i.i.i.i104 = and i64 %4, 70368744177660
(gdb) n
15 %5 = load i8** @global, align 8
(gdb) n
18 store i32 16843009, i32* %6, align 1
(gdb) n
19 store i8 1, i8* getelementptr inbounds ([1 x i8]* @array,
i64 0, i64 0), align 1
(gdb) n
20 call coldcc void @runtime_func() nounwind
(gdb) n
11 while(i-- > argc)
(gdb) n
23 %and.i.i.i.i85 = and i64 %7, 70368744177660
(gdb) n
14 while(j++ < i) k += j;
(gdb) n
11 while(i-- > argc)
(gdb) n
14 while(j++ < i) k += j;
(gdb) n
102 %77 = load i8** @global, align 8
(gdb) n
105 %79 = load i32* %78, align 4
(gdb) n
106 %cmp7.i.i.i = icmp ne i32 %79, 0
(gdb) n
108 call void @llvm.memset.p0i8.i64(i8* %add.ptr.i.i.i.i86, i8
%conv8.i.i.i, i64 4, i32 1, i1 false) nounwind
(gdb) n
14 while(j++ < i) k += j;
(gdb) n
15 while(j-- > 0) k *= k + j;
(gdb) n
95 %69 = load i8** @global, align 8
(gdb) n
98 %71 = load i32* %70, align 4
(gdb)
pass 本身相当简单——它解决的难题是将 IR 发送到磁盘并推断指令 * 在哪一行,如果在 LLVM 中正确完成,这真的不应该成为问题。如果需要,我当然可以根据要求提供代码。
简而言之,它对我来说似乎很有效,并且在 LLVM 本身中正确完成它会很棒!
不幸的是,该代码似乎不可用。