如何使用 WinDBG 和 SOS 调试进程内托管的 ASP.Net 核心应用程序?

How to debug in-process hosted ASP.Net Core apps with WinDBG and SOS?

我有一个 ASP.Net Core 2.2 应用程序,针对 .Net Core 2.2。我使用新的 in-process hosting model 在 Azure App Service 上托管它。 然后我通过应用服务诊断工具创建内存转储。使用 Visual Studio 打开它,我看到两个 CLR 版本:4.7.3190.0; 4.6.27110.4。我可以看出 4.7.3190.0 适用于 .Net Framework,而 4.6.27110.4 适用于 .Net Core。 如果我在 WinDBG 中打开转储,它会继续加载 4.7.3190.0 的 mscordacwks DLL。我无法让它为 4.6.27110.4 加载 mscordaccore DLL。因此,诸如 !Threads 之类的简单 SOS 命令会导致错误 Failed to request ThreadStore.

如何使用 WinDBG 和 SOS 调试托管代码(.Net Core 部分)?

您可以获得示例内存转储 here

更新

感谢 Thomas Weller 的大力帮助!这种情况的解决方法是运行.cordll -u -I coreclr -l -lp "C:\Program Files\dotnet\shared\Microsoft.NETCore.App.2.0\"。我必须在一个命令中卸载 (-u) CLR DAC 并加载 (-l) Core CLR DAC。

成功的命令和日志是here

一般来说,我会说,看看 .cordll 命令。具体来说,

0:000> .cordll -u
CLR DLL status: No load attempts

卸载 CLR DAC 和

0:000> .cordll -I coreclr -l -lp "C:\Program Files\dotnet\shared\Microsoft.NETCore.App.2.0\"
CLR DLL status: Loaded DLL f:\debug\symbols\mscordaccore_AMD64_AMD64_4.6.27110.04.dllBE756335c6000\mscordaccore_AMD64_AMD64_4.6.27110.04.dll

从特定路径加载 .NET Core DAC。


在您的故障转储中,有 2 个 CLR 版本:

0:000> lm m *clr
start             end                 module name
00007ffc`ac990000 00007ffc`acf56000   coreclr    (deferred)             
00007ffc`c2130000 00007ffc`c2b1d000   clr        (deferred)

详情为

0:000> lmvm clr
[...]
    File version:     4.7.3190.0
0:000> lmvm coreclr
[...]
    File version:     4.6.27110.4

如Visual Studio所示。

如果您执行通常的 .loadby sos clr,它将从 clr 所在的位置加载 4.7 版本的 SOS。不幸的是,.loadby sos coreclr 不会以同样的方式工作,因为调试支持不是以与 .NET 相同的方式提供给 .NET Core 的。

0:000> .loadby sos coreclr
The call to LoadLibrary(D:\Program Files\dotnet\shared\Microsoft.NETCore.App.2.0\sos) failed
Win32 error 0n126 "The specified module could not be found."

如果你安装了配套的.NET Core包,在C:\Program Files\dotnet\shared\Microsoft.NETCore.App.2.0\这样的路径下有一些SOS版本。然后您可以从该路径显式加载扩展:

0:000> .load C:\Program Files\dotnet\shared\Microsoft.NETCore.App.2.0\sos.dll

确保卸载 CLR 的 SOS:

0:000> .unload C:\...\sos.dll

并检查 .chain 是否只加载了一个 SOS。