WinDbg";加载数据访问DLL失败"



有一个.NET应用程序似乎在非托管堆中存在内存泄漏。我发现了一个很有前途的博客,它解释了如何调试非托管堆,并跟踪堆帧直到导致内存分配的托管函数(https://www.deleaker.com/blog/2021/03/19/unmanaged-memory-leaks-in-dotnet/)。由于我是第一次使用windbg,我决定重复博客中的例子。我复制粘贴了代码,下载了调试工具包,并按照建议使用了windbg。以下是我陷入困境的原因:

Microsoft (R) Windows Debugger Version 10.0.22000.194 AMD64
Copyright (c) Microsoft Corporation. All rights reserved.
*** wait with pending attach
************* Path validation summary **************
Response                         Time (ms)     Location
Deferred                                       srv*
Symbol search path is: srv*
Executable search path is: 
ModLoad: 00000000`00120000 00000000`00128000   C:<MyPath>WinDbgTest.exe
ModLoad: 00007ffe`c4c10000 00007ffe`c4e05000   C:WINDOWSSYSTEM32ntdll.dll
ModLoad: 00000000`77800000 00000000`779a3000   ntdll.dll
ModLoad: 00007ffe`c3180000 00007ffe`c31d9000   C:WINDOWSSystem32wow64.dll
ModLoad: 00007ffe`c30d0000 00007ffe`c3153000   C:WINDOWSSystem32wow64win.dll
ModLoad: 00000000`777f0000 00000000`777fa000   C:WINDOWSSystem32wow64cpu.dll
ModLoad: 00000000`74890000 00000000`748e2000   mscoree.dll
ModLoad: 00000000`75e50000 00000000`75f40000   KERNEL32.dll
ModLoad: 00000000`76f40000 00000000`77154000   KERNELBASE.dll
ModLoad: 00000000`756b0000 00000000`7572a000   ADVAPI32.dll
ModLoad: 00000000`75730000 00000000`757ef000   msvcrt.dll
ModLoad: 00000000`75be0000 00000000`75c55000   SECHOST.dll
ModLoad: 00000000`76610000 00000000`766d0000   RPCRT4.dll
ModLoad: 00000000`74760000 00000000`747ed000   mscoreei.dll
ModLoad: 00000000`766d0000 00000000`76715000   SHLWAPI.dll
ModLoad: 00000000`74750000 00000000`7475f000   AppCore.dll
ModLoad: 00000000`74e30000 00000000`74e38000   VERSION.dll
ModLoad: 00000000`707a0000 00000000`70f50000   clr.dll 
ModLoad: 00000000`75890000 00000000`75a26000   USER32.dll
ModLoad: 00000000`774e0000 00000000`774f8000   win32u.dll
ModLoad: 00000000`705b0000 00000000`7065b000   ucrtbase_clr0400.dll
ModLoad: 00000000`70660000 00000000`70674000   VCRUNTIME140_CLR0400.dll
ModLoad: 00000000`76ec0000 00000000`76ee3000   GDI32.dll
ModLoad: 00000000`75c60000 00000000`75d3c000   gdi32full.dll
ModLoad: 00000000`76810000 00000000`7688b000   msvcp_win.dll
ModLoad: 00000000`75a30000 00000000`75b50000   ucrtbase.dll
ModLoad: 00000000`75f50000 00000000`75f75000   IMM32.dll
ModLoad: 00000000`6f180000 00000000`7058e000   mscorlib.ni.dll
ModLoad: 00000000`76060000 00000000`76143000   ole32.dll
ModLoad: 00000000`77560000 00000000`777e2000   combase.dll
ModLoad: 00000000`76e50000 00000000`76ead000   bcryptPrimitives.dll
ModLoad: 00000000`6f0f0000 00000000`6f17a000   clrjit.dll
ModLoad: 00000000`757f0000 00000000`75886000   OLEAUT32.dll
(745c.6ac0): Break instruction exception - code 80000003 (first chance)
ntdll!DbgBreakPoint:
00007ffe`c4cb0810 cc              int     3
0:005> !heap -s

************************************************************************************************************************
NT HEAP STATS BELOW
************************************************************************************************************************
NtGlobalFlag enables following debugging aids for new heaps:
stack back traces
LFH Key                   : 0xca6fcf0f30c2eb6b
Termination on corruption : ENABLED
Heap     Flags   Reserv  Commit  Virt   Free  List   UCR  Virt  Lock  Fast 
(k)     (k)    (k)     (k) length      blocks cont. heap 
-------------------------------------------------------------------------------------
0000000001db0000 08000002      60     32     60     11     5     1    0      0      
0000000000150000 08008000      64      4     64      2     1     1    0      0      
-------------------------------------------------------------------------------------
0:005> !heap -stat -h 0000000001db0000
heap @ 0000000001db0000
group-by: TOTSIZE max-display: 20
size     #blocks     total     ( %) (percent of total busy bytes)
2094 1 - 2094  (48.69)
838 1 - 838  (12.28)
800 1 - 800  (11.96)
120 5 - 5a0  (8.41)
1d8 2 - 3b0  (5.51)
100 3 - 300  (4.48)
238 1 - 238  (3.32)
50 4 - 140  (1.87)
42 3 - c6  (1.16)
3c 2 - 78  (0.70)
62 1 - 62  (0.57)
48 1 - 48  (0.42)
30 1 - 30  (0.28)
28 1 - 28  (0.23)
10 1 - 10  (0.09)
4 1 - 4  (0.02)
0:005> !heap -flt s 2094
_HEAP @ 1db0000
HEAP_ENTRY Size Prev Flags            UserPtr UserSize - state
0000000001db10c0 020c 0000  [00]   0000000001db10f0    02094 - (busy)
unknown!printable
_HEAP @ 150000
0:005> !heap -p -a 0000000001db10f0
address 0000000001db10f0 found in
_HEAP @ 1db0000
HEAP_ENTRY Size Prev Flags            UserPtr UserSize - state
0000000001db10c0 020c 0000  [00]   0000000001db10f0    02094 - (busy)
unknown!printable
7ffec4c3b49d ntdll!RtlpAllocateHeapInternal+0x0000000000000a7d
7ffec4c5dce1 ntdll!RtlpInitEnvironmentBlock+0x0000000000000049
7ffec4ce27c1 ntdll!LdrpInitializeProcess+0x0000000000000ba1
7ffec4c84ceb ntdll!LdrpInitialize+0x000000000000015f
7ffec4c84b73 ntdll!LdrpInitialize+0x000000000000003b
7ffec4c84b1e ntdll!LdrInitializeThunk+0x000000000000000e

0:005> .load C:<DllPath>WinDbgDllssos.dll
0:005> !ip2md 7ffec4c84b1e
Failed to load data access DLL, 0x80004005
Verify that 1) you have a recent build of the debugger (6.2.14 or newer)
2) the file mscordacwks.dll that matches your version of clr.dll is 
in the version directory or on the symbol path
3) or, if you are debugging a dump file, verify that the file 
mscordacwks_<arch>_<arch>_<version>.dll is on your symbol path.
4) you are debugging on supported cross platform architecture as 
the dump file. For example, an ARM dump file must be debugged
on an X86 or an ARM machine; an AMD64 dump file must be
debugged on an AMD64 machine.
You can also run the debugger command .cordll to control the debugger's
load of mscordacwks.dll.  .cordll -ve -u -l will do a verbose reload.
If that succeeds, the SOS command should work on retry.
If you are debugging a minidump, you need to make sure that your executable
path is pointing to clr.dll as well.
0:005> .cordll -ve -u -l
CLR DLL status: No load attempts

在我打电话之前一切似乎都正常!ip2md,这里来了一个";加载数据访问DLL失败";。根据一些谷歌搜索结果,我将clr.dll、SOS.dll和mscordacwks.dll放在一个文件夹中,并确保它们都具有相同的位和相同的版本。

如何继续?

让.NET决定加载哪个版本,而不是加载位于PC上某个位置的特定版本的SOS。

更换

.load C:<DllPath>WinDbgDllssos.dll

通过

.loadby sos clr

这个命令告诉WinDbg从加载CLR的任何位置加载SOS扩展。这将确保版本匹配,DAC也匹配。

.loadby可能取决于.NET版本

.loadby sos mscorwks    ; *** .NET 2
.loadby sos clr         ; *** .NET 4
.loadby sos coreclr     ; *** Silverlight and .NET Core

最新更新