注释
本文特定于 .NET Framework。 它不适用于 .NET 的较新版本实现,包括 .NET 6 及更高版本。
编译非托管代码时,可以通过设置 IDE 开关或命令行选项来配置可执行映像进行调试。 例如,可以使用 Visual C++ 中的 /Zi 命令行选项来请求它发出调试符号文件(文件扩展名 .pdb)。 同样,/Od 命令行选项会告知编译器禁用优化。 生成的代码运行速度较慢,但调试起来更容易,这一点是必要的。
编译 .NET Framework 托管代码时,Visual C++、Visual Basic 和 C# 等编译器将其源程序编译为公共中间语言(CIL)。 随后,在执行前将 CIL 实时编译为本机代码。 与非托管代码一样,可以通过设置 IDE 开关或命令行选项来配置可执行映像进行调试。 还可以以完全相同的方式配置 JIT 编译进行调试。
此 JIT 配置具有两个方面:
可以请求 JIT 编译器生成跟踪信息。 这样,调试器就可以将 CIL 链与其计算机代码对应项匹配,并跟踪本地变量和函数参数的存储位置。 在 .NET Framework 版本 2.0 及更高版本中,JIT 编译器始终生成跟踪信息,因此无需请求它。
可以请求 JIT 编译器不优化生成的计算机代码。
通常,生成 CIL 的编译器会根据指定的 IDE 开关或命令行选项(例如 /Od)相应地设置这些 JIT 编译器选项。
在某些情况下,你可能想要更改 JIT 编译器的行为,以便生成的计算机代码更易于调试。 例如,你可能想要为零售构建或控制优化生成 JIT 跟踪信息。 可以使用初始化(.ini)文件执行此作。
例如,如果要调试的程序集 称为MyApp.exe,则可以在 MyApp.exe所在的文件夹中创建名为MyApp.ini的 文本文件,其中包含 以下三行:
[.NET Framework Debugging Control]
GenerateTrackingInfo=1
AllowOptimize=0
可以将每个选项的值设置为 0 或 1,任何缺席选项都默认为 0。 设置为 GenerateTrackingInfo
1 和 AllowOptimize
0 提供最简单的调试。
从 .NET Framework 2.0 开始,JIT 编译器始终生成跟踪信息,不考虑 GenerateTrackingInfo
的值;但是,AllowOptimize
的值仍然有影响。 如果使用 Ngen.exe(本机映像生成器)预编译本机映像而不进行优化,Ngen.exe 执行时 .ini 文件必须存在于 AllowOptimize=0
的目标文件夹。 如果已预编译程序集而不进行优化,则必须使用 NGen.exe /uninstall 选项删除预编译代码,然后重新运行 Ngen.exe 以将代码预编译为优化。 如果文件夹中不存在 .ini 文件,则默认情况下 Ngen.exe 将代码预编译为优化。
System.Diagnostics.DebuggableAttribute 控制程序集的设置。 DebuggableAttribute 包括两个字段,用于控制 JIT 编译器是否应优化和/或生成跟踪信息。 在 .NET Framework 2.0 及更高版本中,JIT 编译器始终生成跟踪信息。
对于零售版本,编译器不会设置任何 DebuggableAttribute。 默认情况下,JIT 编译器会生成性能最高的、最难调试计算机代码。 启用 JIT 跟踪会略微降低性能,而禁用优化会大幅降低性能。
DebuggableAttribute 一次应用于整个程序集,不适用于程序集中的单个模块。 因此,如果已创建程序集或名为 System.Runtime.CompilerServices.AssemblyAttributesGoHere 的类,则开发工具必须将自定义属性附加到程序集元数据令牌。 然后,ALink 工具会将这些 DebuggableAttribute 属性从每个模块提升到它们成为其一部分的程序集。 如果存在冲突,ALink 操作将失败。
注释
在 .NET Framework 版本 1.0 中,Microsoft Visual C++ 编译器在指定 /clr 和 /Zi 编译器选项时添加 DebuggableAttribute。 在 .NET Framework 版本 1.1 中,必须在代码中手动添加 DebuggableAttribute 或使用 /ASSEMBLYDEBUG 链接器选项。