0

Recently I needed to debug a memory dump of a CLR process where the finalization queue was being blocked by a COM object. While I have largely identified the issue, I am not sure about the difference between some of the output and seek some clarification.

I used SOSEX to dump the RCWs. The output is as follows:

0:019> !sosex.rcw
SyncBlock           OwnerObject           RCW                RefCount   IUnknown           VTable             
------------------------------------------------------------------------------------------------------------
000000811807b238    0000008118251e18      00000081176b02e0          0   0000008116a6bc68   0061005c00730077
000000811807b5f8    00000081182b7380      0000008118104590          0   0000008116a6bc68   004d005c00730077
0000008562fed748    000000811831f498      0000008562fe7510        129   0000008116a6bc68   00000085632a2ee0
000000856300e168    00000084182ae2f0      0000008563082d00          0   0000008116a6bc68   000000856306a660
--------------
4 RCWs

Dumping the vtable does not help identify the COM object.

0:019> dps 00000085632a2ee0
00000085`632a2ee0  00007ffc`31832938 clr!DomainAssembly::`vftable'
00000085`632a2ee8  00000081`18099170
00000085`632a2ef0  00000085`631db8d0
00000085`632a2ef8  00000000`00000000
00000085`632a2f00  00007ffb`d24e4d20
00000085`632a2f08  0063006e`0000000c
00000085`632a2f10  00000085`1833ade9
00000085`632a2f18  00000000`00000000
00000085`632a2f20  00000001`00000007
00000085`632a2f28  00000000`00000000
00000085`632a2f30  00000000`00000000
00000085`632a2f38  00000000`00000000
00000085`632a2f40  00530041`002f0073
00000085`632a2f48  00000085`1833ade1
00000085`632a2f50  00000085`62fe7600
00000085`632a2f58  00000085`631dbd50
0:019> dps 00007ffc`31832938
00007ffc`31832938  00007ffc`31220ac0 clr!DomainAssembly::`vector deleting destructor'
00007ffc`31832940  00007ffc`311405d0 clr!CAssemblyIdentityManager::AddRef
00007ffc`31832948  00007ffc`3119e080 clr!DomainAssembly::Begin
00007ffc`31832950  00007ffc`3119fbe0 clr!DomainAssembly::Allocate
00007ffc`31832958  00007ffc`3119f0f0 clr!DomainAssembly::DeliverSyncEvents
00007ffc`31832960  00007ffc`3119e4d0 clr!DomainAssembly::DeliverAsyncEvents
00007ffc`31832968  00007ffc`311a01c0 clr!DomainAssembly::FindNativeImage
00007ffc`31832970  00007ffc`3160d630 clr!CorHostProtectionManager::QueryInterface
00007ffc`31832978  00007ffc`311405d0 clr!CAssemblyIdentityManager::AddRef
00007ffc`31832980  00007ffc`311405d0 clr!CAssemblyIdentityManager::AddRef
00007ffc`31832988  00007ffc`3160d660 clr!CorHostProtectionManager::SetProtectedCategories
00007ffc`31832990  00007ffc`31406100 clr!CorHostProtectionManager::SetEagerSerializeGrantSets
00007ffc`31832998  00007ffc`31500a30 clr!CCLRErrorReportingManager::QueryInterface
00007ffc`318329a0  00007ffc`311405d0 clr!CAssemblyIdentityManager::AddRef
00007ffc`318329a8  00007ffc`311405d0 clr!CAssemblyIdentityManager::AddRef
00007ffc`318329b0  00007ffc`314fcc50 clr!CCLRErrorReportingManager::GetBucketParametersForCurrentException

However, if I use !sos.dumprcw, a different vtable (and IUnknown) address is displayed:

0:019> !sos.dumprcw 0000008562fe7510
Managed object:             000000811831f498
Creating thread:            0000008562ff0050
IUnknown pointer:           000000811693a8d0
COM Context:                0000008116a6bc68
Managed ref count:          1
IUnknown V-table pointer :  00007ffc33609078 (captured at RCW creation time)
Flags:                      
COM interface pointers:
              IP          Context               MT Type
000000811693a8d0 0000008116a6bc68 00007ffbd19db8c8 Microsoft.Web.Administration.Interop.IAppHostAdminManager

Dumping this "IUnknown V-table pointer" identifies the source of the COM reference.

0:019> dps 00007ffc33609078 
00007ffc`33609078  00007ffc`33607cb0 nativerd!CONFIG_SYSTEM::QueryInterface
00007ffc`33609080  00007ffc`33605750 nativerd!CONFIG_SYSTEM::AddRef
00007ffc`33609088  00007ffc`33605700 nativerd!CONFIG_SYSTEM::Release
00007ffc`33609090  00007ffc`33627fe0 nativerd!CONFIG_SYSTEM::GetAdminSection
00007ffc`33609098  00007ffc`33603fb0 nativerd!CONFIG_SYSTEM::GetMetadata
00007ffc`336090a0  00007ffc`33609e40 nativerd!CONFIG_SYSTEM::SetMetadata
00007ffc`336090a8  00007ffc`3364fc30 nativerd!CONFIG_SYSTEM::get_ConfigManager
00007ffc`336090b0  00007ffc`3364ecc0 nativerd!CONFIG_SYSTEM::CommitChanges
00007ffc`336090b8  00007ffc`3363c7d0 nativerd!CONFIG_SYSTEM::get_CommitPath
00007ffc`336090c0  00007ffc`336235c0 nativerd!CONFIG_SYSTEM::put_CommitPath
00007ffc`336090c8  00007ffc`33626190 nativerd!CONFIG_SYSTEM::`vector deleting destructor'
00007ffc`336090d0  00007ffc`3362e780 nativerd!CONFIG_MAPPING_EXTENSION::QueryInterface
00007ffc`336090d8  00007ffc`33604730 nativerd!CONFIG_MAPPING_EXTENSION::AddRef
00007ffc`336090e0  00007ffc`33604190 nativerd!CONFIG_MAPPING_EXTENSION::Release
00007ffc`336090e8  00007ffc`336530c0 nativerd!CONFIG_MAPPING_EXTENSION::GetSiteNameFromSiteId
00007ffc`336090f0  00007ffc`33652e20 nativerd!CONFIG_MAPPING_EXTENSION::GetSiteIdFromSiteName

What is the difference between the !sos.dumprcw and !sosex.rcw output in regards to vtable?

Dono
  • 1,254
  • 13
  • 30
  • The dumprcw command revealed the RCW for the IAppHostAdminManager interface. Chasing the interface pointer took you to the concrete implementation of the interface. Buried in the C++ bowels of the IIS extension that implements the asp.net host, by the looks of it. – Hans Passant Oct 26 '18 at 17:30
  • @HansPassant Yes, that was my conclusion as well. I was hoping to identify which component in our code base was creating instances of IAppHostAdminManager, but it seems to be an internal interface in Microsoft.Web.Administration.dll, so Microsoft.Web.Administration.ServerManager seems to be the only likely candidate. It wasn't being disposed properly and is getting stuck in finalization. Back to the main question, though, I would like to know why the vtable address being reported by !sos.dumprcw and !sosex.rcw are different. The vtable reported by !sosex.rcw does not seem useful (or wrong?). – Dono Oct 27 '18 at 04:03

0 Answers0