让我向您展示以下简单的C代码:
int main()
{
int i;
for (i = 0; i < 256; i++)
{
i++;
}
}
在这个简单的C代码中,如果我们使用Clang编译并调试它: 我们会得到这样的东西:
(gdb) b main
Breakpoint 1 at 0x100000f7b: file a.c, line 5.
(gdb) r
Starting program: a.out
[New Thread 0x1403 of process 23435]
warning: unhandled dyld version (15)
Thread 2 hit Breakpoint 1, main () at a.c:5
5 for (i = 0; i < 256; i++)
(gdb) n
7 i++;
(gdb)
5 for (i = 0; i < 256; i++)
(gdb)
7 i++;
也就是说,位置LLVM的右支撑不会发出。但是,如果我们有continue关键字:
int main()
{
int i;
for (i = 0; i < 256; i++)
{
continue;
i++;
}
}
然后我们编译并调试它:
Thread 2 hit Breakpoint 1, main () at a.c:5
5 for (i = 0; i < 256; i++)
(gdb) n
7 continue;
(gdb)
5 for (i = 0; i < 256; i++)
(gdb)
7 continue;
(gdb)
5 for (i = 0; i < 256; i++)
(gdb)
7 continue;
我们将停止继续行。但是,如果我们比较它们之间的LLVM IR:
右括号和continue关键字都是以下br指令和!dbg!23。除了!dbg!23的行号不一样。
:6 :; preds =%3 br标签%7,!dbg!23
问题是LLVM如何知道是否生成调试位置(为continue关键字行生成,但不为循环的右大括号生成)?因为它们是相同的指令而其他指令是相同的。
答案 0 :(得分:1)
大括号只是一个语法范围,编译器之间存在 no 的区别:
30
和
for (i = 0; i < 256; i++)
{
i++;
}
解析器正在使用您创建的作用域将语句组合在一起,但这将 not 出现在LLVM IR中。 LLVM IR代表程序需要执行的更多指令。
在调试器中使用for (i = 0; i < 256; i++)
i++;
时,要求继续执行程序,直到找到与不同源代码行对应的指令。大括号与可执行文件中的任何指令都不对应。