使用 Windows 调试器调试托管代码

可以使用 Windows 调试器 (WinDbg、CDB 和 NTSD) 来调试包含托管代码的目标应用程序。 若要调试托管代码,必须加载 SOS 调试扩展 (sos.dll) 和数据访问组件 (mscordacwks.dll) 。

Windows 调试器独立于 Visual Studio 调试器。 有关 Windows 调试器和 Visual Studio 调试器之间的区别的信息,请参阅 Windows 调试

托管代码简介

托管代码与 Microsoft .NET 公共语言运行时 (CLR) 一起执行。 在托管代码应用程序中,编译器生成的二进制代码采用与平台无关的 Microsoft 中间语言 (MSIL) 。

运行托管代码时,运行时将生成特定于平台的本机代码。 从 MSIL 生成本机代码的过程称为 实时 (JIT) 编译。 JIT 编译器为特定方法编译 MSIL 后,该方法的本机代码将保留在内存中。 每当以后调用此方法时,都会执行本机代码,并且无需涉及 JIT 编译器。

可以使用由各种软件生成者制造的多个编译器来生成托管代码。 具体而言,Microsoft Visual Studio 可以使用多种不同语言(包括 C#、Visual Basic、JScript 和 C++ 和托管扩展)生成托管代码。

每次更新.NET Framework时,CLR 都不会更新。 例如,2.0 版、3.0 版和 3.5 版.NET Framework都使用 2.0 版 CLR。 下表显示了每个版本的.NET Framework使用的 CLR 的版本和文件名。

.NET Framework 版本 CLR 版本 CLR 文件名
1.1 1.1 mscorwks.dll
2.0 2.0 mscorwks.dll
3.0 2.0 mscorwks.dll
3.5 2.0 mscorwks.dll
4.0 4.0 clr.dll
4.5 4.0 clr.dll

调试托管代码

若要调试托管代码,调试器必须加载这两个组件。

注意对于所有版本的.NET Framework,DAC 的文件名 mscordacwks.dll,SOS 调试扩展的文件名 sos.dll。

获取 SOS 调试扩展 (sos.dll)

当前版本的 Windows 调试工具中不包含 SOS 调试扩展 (sos.dll) 文件。

对于 .NET Framework 2.0 及更高版本,.NET Framework安装中包含 sos.dll。

对于版本 1。.NET Framework的 x,sos.dll 不包括在.NET Framework安装中。 获取.NET Framework 1 的 sos.dll。x,下载 32 位版本的 Windows 7 Windows 调试工具。

适用于 Windows 的 Windows 7 调试工具包含在适用于 Windows 7 的 Windows SDK 中,可在以下两个位置使用:

如果运行的是 x64 版本的 Windows,请使用 ISO,以便可以指定需要 32 位版本的 SDK。 Sos.dll 仅包含在 32 位版本的 Windows 7 Windows 调试工具中。

加载 mscordacwks.dll 并 sos.dll (实时调试)

假设调试器和要调试的应用程序在同一台计算机上运行。 然后,应用程序使用的.NET Framework将安装在计算机上,并且可供调试器使用。

调试器必须加载与托管代码应用程序使用的 CLR 版本相同的 DAC 版本。 (32 位或 64 位) 位也必须匹配。 DAC (mscordacwks.dll) 附带.NET Framework。 若要加载正确版本的 DAC,请将调试器附加到托管代码应用程序,然后输入此命令。

.cordll -ve -u -l

输出应与此类似。

CLRDLL: Loaded DLL C:\Windows\Microsoft.NET\Framework64\v4.0.30319\mscordacwks.dll
CLR DLL status: Loaded DLL C:\Windows\Microsoft.NET\Framework64\v4.0.30319\mscordacwks.dll

若要验证 mscordacwks.dll 的版本是否与应用程序使用的 CLR 版本匹配,请输入以下命令之一以显示有关加载的 CLR 模块的信息。

适用于 4.0 版 CLR) 的 lmv mclr (

lmv mscorwks (,适用于 1.0 版或 2.0 版 CLR)

输出应与此类似。

start             end                 module name
000007ff`26710000 000007ff`2706e000   clr        (deferred)             
    Image path: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll
...

在前面的示例中,请注意,CLR (clr.dll) 的版本与 DAC (mscordacwks.dll) :v4.0.30319 的版本匹配。 另请注意,这两个组件都是 64 位的。

使用 .cordll 加载 DAC 时,SOS 调试扩展 (sos.dll) 可能会自动加载。 如果 sos.dll 未自动加载,可以使用其中一个命令来加载它。

适用于 4.0 版 CLR) 的 .loadby sos clr (

.loadby sos mscorwks (1.0 或 2.0 版 CLR)

作为使用 .loadby 的替代方法,可以使用 .load。 例如,若要加载 64 位 CLR 的 4.0 版,可以输入如下所示的命令。

.load C:\Windows\Microsoft.NET\Framework64\v4.0.30319\sos.dll

在前面的输出中,请注意,SOS 调试扩展 (sos.dll) 的版本与 CLR 和 DAC 的版本匹配:v4.0.30319。 另请注意,所有三个组件都是 64 位的。

加载 mscordacwks.dll 和 sos.dll (转储文件)

假设使用调试器打开在另一台计算机上创建的托管代码应用程序) (转储文件。

调试器必须加载与托管代码应用程序在其他计算机上使用的 CLR 版本相同的 DAC 版本。 (32 位或 64 位) 位也必须匹配。

DAC (mscordacwks.dll) 附带.NET Framework,但假设运行调试器的计算机上没有安装正确版本的.NET Framework。 你有三个选项。

  • 从符号服务器加载 DAC。 例如,可以在符号路径中包含 Microsoft 的公共符号服务器。
  • 在运行调试器的计算机上安装正确版本的 .NET Framework。
  • 从另一台计算机 (创建转储文件的人员获取正确版本的 mscordacwks.dll) ,并手动将其复制到运行调试器的计算机。

下面我们将说明如何使用 Microsoft 的公共符号服务器。

输入这些命令。

.sympath+ srv\* (将符号服务器添加到符号路径。)

!sym noisy

.cordll -ve -u -l

输出将与此类似。

CLRDLL: Unable to get version info for 'C:\Windows\Microsoft.NET
   \Framework64\v4.0.30319\mscordacwks.dll', Win32 error 0n87

SYMSRV:  C:\ProgramData\dbg\sym\mscordacwks_AMD64_AMD64_4.0.30319.18010.dll
   \5038768C95e000\mscordacwks_AMD64_AMD64_4.0.30319.18010.dll not found

SYMSRV:  mscordacwks_AMD64_AMD64_4.0.30319.18010.dll from 
   https://msdl.microsoft.com/download/symbols: 570542 bytes - copied         
...
SYMSRV:  C:\ProgramData\dbg\sym\SOS_AMD64_AMD64_4.0.30319.18010.dll
   \5038768C95e000\SOS_AMD64_AMD64_4.0.30319.18010.dll not found

SYMSRV:  SOS_AMD64_AMD64_4.0.30319.18010.dll from 
   https://msdl.microsoft.com/download/symbols: 297048 bytes - copied         
...
Automatically loaded SOS Extension
...

在前面的输出中,可以看到调试器首先在本地计算机上查找 C:\Windows\Microsoft.NET 中的 mscordacwks.dll 和 sos.dll,并在符号缓存中查找 (C:\ProgramData\dbg\sym) 。 当调试器在本地计算机上找不到正确版本的文件时,它会从公共符号服务器检索这些文件。

若要验证 mscordacwks.dll 的版本是否与应用程序使用的 CLR 版本匹配,请输入以下命令之一以显示有关加载的 CLR 模块的信息。

适用于 4.0 版 CLR) 的 lmv -mclr (

lmv -mscorwks (1.0 或 2.0 版 CLR)

输出应与此类似。

start             end                 module name
000007ff`26710000 000007ff`2706e000   clr        (deferred)             
    Image path: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll
...

在前面的示例中,请注意 CLR (clr.dll) 的版本与 DAC (mscordacwks.dll) 的产品版本匹配:v4.0.30319。 另请注意,这两个组件都是 64 位的。

使用 SOS 调试扩展

若要验证是否正确加载了 SOS 调试扩展,请输入 .chain 命令。

0:000> .chain
Extension DLL search Path:
...
Extension DLL chain:
    C:\ProgramData\dbg\sym\SOS_AMD64_AMD64_4.0.30319.18010.dll\...
        ...
    dbghelp: image 6.13.0014.1665, API 6.2.6, built Wed Dec 12 03:02:43 2012
...

若要测试 SOS 调试扩展,请输入 !sos.help。 然后尝试 SOS 调试扩展提供的命令之一。 例如,可以尝试 !sos。DumpDomain!sos。Threads 命令。

备注

有时,托管代码应用程序会加载多个版本的 CLR。 在这种情况下,必须指定要加载的 DAC 版本。 有关详细信息,请参阅 .cordll