8

调试器(或 CLR 异常处理程序)是否可以使用 pdb 显示在发布模式下发生异常的行?

发布模式下的代码经过优化,并不总是遵循“原始”代码的顺序和逻辑。

令人惊讶的是,即使在发布模式下,调试器也可以逐步浏览我的代码。优化应该使导航非常不舒服。

能否请您为我澄清这两点?

4

4 回答 4

12

我不太熟悉如何使用 CLR 完成此操作,但它可能与使用本机代码完成的方式非常相似。当编译器生成机器指令时,它会向 pdb 添加条目,基本上说“当前地址 X 处的指令来自 foo.cpp 中的第 25 行”。

调试器知道当前正在执行的程序地址。因此它在 pdb 中查找某个地址 X,并发现它来自 foo.cpp 中的第 25 行。使用它,它能够“逐步”通过您的源代码。

无论 Debug 还是 Release 模式,这个过程都是一样的(前提是在 Release 模式下完全生成了一个 pdb)。但是,您是对的,由于优化,调试器通常在发布模式下不会“线性”地通过代码。它可能会意外跳到不同的行。这是由于优化器改变了指令的顺序,但它并没有改变地址到源行的映射,所以调试器仍然能够遵循它。

于 2009-06-01T17:47:19.253 回答
1

[@Not Sure] 几乎是对的。编译器尽最大努力识别与当前机器代码指令密切匹配的适当行号。

PDB 和调试器对优化一无所知;PDB 文件本质上将机器代码中的地址位置映射到源代码行号。在优化的代码中,并不总是可以将汇编指令与特定的源代码行完全匹配,因此编译器会将其手头最接近的内容写入 PDB。这可能是“之前的源代码行”,或“封闭上下文(循环等)的源代码行”或其他内容。

无论如何,调试器基本上会在 PDB 映射中找到最接近当前 IP(指令指针)的条目(如“之前或等于”)并突出显示该行。

有时匹配不是很好,那就是当您看到突出显示的区域在整个地方跳跃时。

于 2009-06-01T18:06:35.293 回答
0

调试器会尽力猜测问题发生的位置。它不能保证 100% 准确,并且使用完全优化的代码,它通常会不准确 - 我发现不准确的地方从几行到完全错误的调用堆栈不等。

调试器对优化代码的准确程度实际上取决于代码本身以及您正在进行哪些优化。

于 2009-06-01T17:11:11.833 回答
0

参考以下 SO 问题:

在发布模式下显示 .NET 程序集的堆栈跟踪中的行号

于 2009-06-01T17:52:41.400 回答