当一个进程中加载多个.NET Runtime的时候如何在托管调试中加载指定的mscordacwks.dll
当多个.NETRuntime加载在一个目标进程或一个dump文件中,例如:
0:030> lm
start end module name
00000000'1b6d0000 00000000'1b9ba000 System_Data (deferred)
...
000007fe'f3e60000 000007fe'f47c5000 clr (deferred)
...
000007fe'f9880000 000007fe'fa230000 mscorwks (deferred)
...
0:030> lmvm clr
start end module name
000007fe'f3e60000 000007fe'f47c5000 clr (deferred)
Image path: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll
Image name: clr.dll
......
CompanyName: Microsoft Corporation
ProductName: Microsoft® .NET Framework
InternalName: clr.dll
OriginalFilename: clr.dll
ProductVersion: 4.0.30319.1
FileVersion: 4.0.30319.1 (RTMRel.030319-0100)
PrivateBuild: DDBLD431
FileDescription: Microsoft .NET Runtime Common Language Runtime - WorkStation
LegalCopyright: © Microsoft Corporation. All rights reserved.
Comments: Flavor=Retail
0:030> lmvm mscorwks
start end module name
000007fe'f9880000 000007fe'fa230000 mscorwks (deferred)
Image path: C:\Windows\Microsoft.NET\Framework64\v2.0.50727\mscorwks.dll
Image name: mscorwks.dll
.......
CompanyName: Microsoft Corporation
ProductName: Microsoft® .NET Framework
InternalName: mscorwks.dll
OriginalFilename: mscorwks.dll
ProductVersion: 2.0.50727.4206
FileVersion: 2.0.50727.4206 (VistaSP2GDR.050727-4200)
FileDescription: Microsoft .NET Runtime Common Language Runtime - WorkStation
LegalCopyright: © Microsoft Corporation. All rights reserved.
Comments: Flavor=Retail
.NET runtime 4.0中的clr.dll 和.NET runtime 2.0中的mscorwks.dll加载在一个进程中,托管调试可能会为错误的结果,如下面所示:
0:030> .loadby sos mscorwks
0:030> !clrstack
OS Thread Id: 0x2674 (30)
Unable to walk the managed stack. The current thread is likely not a managed thread. You can run !threads to get a list of managed threads in the process
其实线程30是一个托管线程,是.NET 2.0 的托管线程 ,但不是.NET 4.0的托管线程。
如果通过使用.cordll 来加载托管调试模块 mscordacwks.dll,如下所示,可以看到调试器总是会默认尝试为最新的.NET runtime加载mscordacwks.dll,在我们的示例里面是.NET runtime 4.0 运行库,这就是解释了为什么.NET runtime 2.0托管线程不能被正常调试。
0:030> .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来进行托管调试?例如,加载托管调试模块.NET runtime 2.0的 mscorwks.dll 吗?假定匹配的 mscordacwks.dll 复制到文件夹 c:\tempzhong ,下列两个命令可以用来加载模块的托管调试:
.cordll -ve -se -u -I <Start address of the target .NET runtime module> -N
或者
.cordll -ve -se -u -I <Start address of the target .NET runtime module> -lp <path of the managed debugging module>
在我们的示例中,该命令为:
*note* -N switch causes the debugger to search the matched mscordacwks.dll in the configured symbol path. -lp switch causes the debugger to load the matched mscordacwks.dll from the specified path.
0:030> .cordll -ve -se -u -I 000007fe'f9880000 -N
CLRDLL: C:\Windows\Microsoft.NET\Framework64\v2.0.50727\mscordacwks.dll:2.0.50727.4952 f:0
doesn't match desired version 2.0.50727.4206 f:0
CLRDLL: Loaded DLL
\\SymbolShare\websymbols\mscordacwks_AMD64_AMD64_2.0.50727.4206.dll\4BF4C1819b0000\mscordacwks_AMD64_AMD64_2.0.50727.4206.dll
CLR DLL status: Loaded DLL
\\SymbolShare\websymbols\mscordacwks_AMD64_AMD64_2.0.50727.4206.dll\4BF4C1819b0000\mscordacwks_AMD64_AMD64_2.0.50727.4206.dll
....
或者
0:030> .cordll -ve -se -u -I 000007fe'f9880000 -lp c:\temp
CLRDLL: Loaded DLL c:\temp\mscordacwks.dll
CLR DLL status: Loaded DLL c:\temp\mscordacwks.dll
现在,通过执行托管调试命令可以得到正确结果。
0:030>.loadby sos mscorwks
0:030> !clrstack
OS Thread Id: 0x2674 (30)
(!clrstack processes a max of 1000 stack frames)
Child-SP RetAddr Call Site
0000000005fb71a0 000007fef6fc79b5 System.Net.Sockets.Socket.MultipleSend(System.Net.BufferOffsetSize[], System.Net.Sockets.SocketFlags)
0000000005fb7290 000007fef6fc747b System.Net.Sockets.NetworkStream.MultipleWrite(System.Net.BufferOffsetSize[])
0000000005fb7310 000007fef6fc7381 System.Net.ConnectStream.ResubmitWrite(System.Net.ConnectStream, Boolean)
0000000005fb73c0 000007fef6fc7240 System.Net.HttpWebRequest.EndWriteHeaders_Part2()
......