Když během svých přednášek používám WinDbg, obvykle vše ukazuji na instancích tříd. Dostávám tedy poměrně často otázku, jak prozkoumat hodnoty statických fieldů tříd, nebo dokonce celé statické třídy.
Statické fieldy
Se statickými fieldy instančních tříd je to jednoduché. Při výpisu instance pomocí !DumpObj <addr> (zkráceně !do) získáme výpis, v němž jsou hodnoty statických fieldů přímo vidět:
0:000> .symfix 0:000> .reload 0:000> .loadby sos clr 0:000> !DumpHeap -type System.Web.HttpRuntime ... 0:000> !DumpObj 075d6c30 Name: System.Web.HttpRuntime MethodTable: 6da63274 EEClass: 6d8321cc Size: 160(0xa0) bytes File: C:\Windows\Microsoft.Net\assembly\GAC_32\System.Web\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Web.dll Fields: MT Field Offset Type VT Attr Value Name 7330b12c 4001238 4 ...amedPermissionSet 0 instance 00000000 _namedPermissionSet 732c14d4 4001239 8 ...olicy.PolicyLevel 0 instance 00000000 _policyLevel 73303e18 400123a c System.String 0 instance 00000000 _hostSecurityPolicyResolverType 6da63884 400123b 10 ...ileChangesMonitor 0 instance 075d7068 _fcm 6da63df0 400123c 14 ...ing.CacheInternal 0 instance 075d8a5c _cacheInternal 6da63e9c 400123d 18 ...Web.Caching.Cache 0 instance 075d8850 _cachePublic 7330f91c 400123e 7c System.Boolean 1 instance 0 _isOnUNCShare 6da63760 400123f 1c ...Web.Util.Profiler 0 instance 075d6cd0 _profiler 6da63798 4001240 20 ...estTimeoutManager 0 instance 075d6cec _timeoutManager 6da6fd80 4001241 24 ....Web.RequestQueue 0 instance 0750215c _requestQueue 7330f91c 4001242 7d System.Boolean 1 instance 0 _apartmentThreading 7330f91c 4001243 7e System.Boolean 1 instance 1 _processRequestInApplicationTrust 7330f91c 4001244 7f System.Boolean 1 instance 1 _disableProcessRequestInApplicationTrust 7330f91c 4001245 80 System.Boolean 1 instance 0 _isLegacyCas 7330f91c 4001246 81 System.Boolean 1 instance 0 _beforeFirstRequest ... 73303e18 4001266 6c System.String 0 instance 00000000 _clientScriptVirtualPath 73303e18 4001267 70 System.String 0 instance 00000000 _clientScriptPhysicalPath 6da63274 4001230 f90 ...m.Web.HttpRuntime 0 shared static _theRuntime >> Domain:Value 01f81230:NotInit 1f443310:0a4d09b4 1e2d62c0:075d6c30 01fc1b88:30105634 51063e70:0aaf2afc << 73306d34 4001231 f94 System.Byte[] 0 shared static s_autogenKeys >> Domain:Value 01f81230:NotInit 1f443310:0a4d0360 1e2d62c0:075d65dc 01fc1b88:30104fe0 51063e70:0aaf24a8 << 73303e18 4001232 f98 System.String 0 shared static DirectorySeparatorString >> Domain:Value 01f81230:NotInit 1f443310:0a4d08dc 1e2d62c0:075d6b58 01fc1b88:3010555c 51063e70:0aaf2a24 << 73303e18 4001233 f9c System.String 0 shared static DoubleDirectorySeparatorString >> Domain:Value 01f81230:NotInit 1f443310:0a4d08ec 1e2d62c0:075d6b68 01fc1b88:3010556c 51063e70:0aaf2a34 << 733047d8 4001234 fa0 System.Char[] 0 shared static s_InvalidPhysicalPathChars >> Domain:Value 01f81230:NotInit 1f443310:0a4d0900 1e2d62c0:075d6b7c 01fc1b88:30105580 51063e70:0aaf2a48 << 7330f91c 4001235 ca2 System.Boolean 1 shared static s_initialized >> Domain:Value 01f81230:NotInit 1f443310:1 1e2d62c0:1 01fc1b88:1 51063e70:1 << 73303e18 4001236 fa4 System.String 0 shared static s_installDirectory >> Domain:Value 01f81230:NotInit 1f443310:0a4d0928 1e2d62c0:075d6ba4 01fc1b88:301055a8 51063e70:0aaf2a70 << 7330f91c 4001237 ca3 System.Boolean 1 shared static s_isEngineLoaded >> Domain:Value 01f81230:NotInit 1f443310:1 1e2d62c0:1 01fc1b88:1 51063e70:1 << 7330652c 4001268 fa8 System.Version 0 shared static _iisVersion >> Domain:Value 01f81230:NotInit 1f443310:024c4a70 1e2d62c0:4209fd30 01fc1b88:3016e81c 51063e70:3e92e40c << 7330f91c 4001269 ca4 System.Boolean 1 shared static _useIntegratedPipeline >> Domain:Value 01f81230:NotInit 1f443310:1 1e2d62c0:1 01fc1b88:1 51063e70:1 << 7330f91c 400126a ca5 System.Boolean 1 shared static _enablePrefetchOptimization >> Domain:Value 01f81230:NotInit 1f443310:0 1e2d62c0:0 01fc1b88:0 51063e70:0 << 6daa0b50 400126b fac ...nloadEventHandler 0 shared static AppDomainShutdown >> Domain:Value 01f81230:NotInit 1f443310:00000000 1e2d62c0:00000000 01fc1b88:00000000 51063e70:00000000 << 6daa3ffc 400126c fb0 ....FactoryGenerator 0 shared static s_factoryGenerator >> Domain:Value 01f81230:NotInit 1f443310:00000000 1e2d62c0:00000000 01fc1b88:00000000 51063e70:00000000 << 733060f0 400126d fb4 ...ections.Hashtable 0 shared static s_factoryCache >> Domain:Value 01f81230:NotInit 1f443310:00000000 1e2d62c0:00000000 01fc1b88:00000000 51063e70:00000000 << 7330f91c 400126e ca6 System.Boolean 1 shared static s_initializedFactory >> Domain:Value 01f81230:NotInit 1f443310:0 1e2d62c0:0 01fc1b88:0 51063e70:0 << 733041b8 400126f fb8 System.Object 0 shared static s_factoryLock >> Domain:Value 01f81230:NotInit 1f443310:0a4d091c 1e2d62c0:075d6b98 01fc1b88:3010559c 51063e70:0aaf2a64 << 73303e18 4001270 fbc System.String 0 shared static _DefaultPhysicalPathOnMapPathFailure >> Domain:Value 01f81230:NotInit 1f443310:00000000 1e2d62c0:00000000 01fc1b88:00000000 51063e70:00000000 <<
Hodnoty statických fieldů jsou ve výstupu !DumpObj přímo vidět. Ve sloupci Attr je uveden shared, ve sloupci Value je uvedeno static a na dalším řádku jsou vyjmenovány hodnoty pro jednotlivé domény. Musíme si zde uvědomit, že každá aplikační doména (AppDomain), jako jednotka izolace, má vlastní statické fieldy. V každé doméně má tedy příslušný typ vlastní hodnoty statických fieldů, popř. tam nemusí být ještě inicializován (NotInit).
Příslušný řádek tedy uvádí pro každou doménu dvojici Domain:Value, přesně jak je naznačeno – vždy adresa příslušné domény a hodnota statického fieldu v ní. (Je zřejmé, že pro libovolnou instanci dostaneme vždy stejný výpis hodnot statických fieldů, instance nám zde slouží jen jako navigace k příslušnému typu.)
Domény
Výpis domén dostaneme příkazem !DumpDomain [addr], bez uvedení adresy se vypíšou všechny:
0:000> !DumpDomain 51063e70 -------------------------------------- Domain 8: 51063e70 LowFrequencyHeap: 510642c4 HighFrequencyHeap: 5106430c StubHeap: 51064354 Stage: OPEN SecurityDescriptor: 50e671b0 Name: /LM/W3SVC/2/ROOT-7-130739961229274429 Assembly: 01f74008 [C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll] ClassLoader: 00fface8 SecurityDescriptor: 4cafd130 Module Name 72f01000 C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll Assembly: 01f73540 [C:\Windows\Microsoft.Net\assembly\GAC_32\System.Web\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Web.dll] ClassLoader: 00ffaa78 SecurityDescriptor: 50825198 ...
Při použití NETEXT můžeme použít přehlednější !wdomain:
0:000> .load D:\NetExt\x86\NetExt.dll NetExt version 2.0.1.5550 Apr 20 2015 License and usage can be seen here: !whelp license Check Latest version: !wupdate For help, type !whelp (or in WinDBG run: '.browse !whelp') Questions and Feedback: http://netext.codeplex.com/discussions Copyright (c) 2014-2015 Rodney Viana (http://blogs.msdn.com/b/rodneyviana) Type: !windex -tree or ~*e!wstack to get started 0:000> !wdomain Address Domain Name Modules Base Path & Config 74690c08 System 55 74690f60 Shared 01f81230 DefaultDomain 10 Base Path: C:\Windows\SysWOW64\inetsrv\ Config: w3wp.exe.config 1f443310 /LM/W3SVC/1/ROOT-1-130739944552644364 232 Base Path: D:\inetpub\www1\ Config: web.config 1e2d62c0 /LM/W3SVC/2/ROOT-1-130739949798771823 207 Base Path: D:\inetpub\www2\ Config: web.config 01fc1b88 /LM/W3SVC/3/ROOT-1-130739955724452334 199 Base Path: D:\inetpub\www3\ Config: web.config 51063e70 /LM/W3SVC/4/ROOT-1-130739961229274429 233 Base Path: D:\inetpub\www4\ Config: web.config
Statické třídy
Trochu jinak je potřeba postupovat, pokud máme statickou třídu, nebo třídu, od které nemáme k dispozici instanci.
Není to nic komplikovaného, jenom musíme pomocí !Name2EE <ModuleName> <ItemName> získat EEClass adresu, kterou pak použijeme do příkazu !DumpClass <EEClassAddr>:
0:000> !name2ee System.Web.dll System.Web.Hosting.PipelineRuntime Module: 6d811000 Assembly: System.Web.dll Token: 02000342 MethodTable: 6da63a6c EEClass: 6d811680 Name: System.Web.Hosting.PipelineRuntime 0:000> !DumpClass 6d811680 Class Name: System.Web.Hosting.PipelineRuntime mdToken: 02000342 File: C:\Windows\Microsoft.Net\assembly\GAC_32\System.Web\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Web.dll Parent Class: 72f03e44 Module: 6d811000 Method Table: 6da63a6c Vtable Slots: 11 Total Method Slots: 16 Class Attributes: 100100 Transparency: Transparent NumInstanceFields: 1 NumStaticFields: 13 MT Field Offset Type VT Attr Value Name 733041b8 400019b 4 System.Object 0 instance __identity 7330560c 4000eb1 c60 System.Int32 1 shared static s_isThisAppDomainRemovedFromUnmanagedTable >> Domain:Value 01f81230:NotInit 1f443310:1 1e2d62c0:1 01fc1b88:1 51063e70:0 << 73302b8c 4000eb2 c64 System.IntPtr 1 shared static s_ApplicationContext >> Domain:Value 01f81230:NotInit 1f443310:018009d0 1e2d62c0:1d85cfa0 01fc1b88:01806498 51063e70:1d87b810 << 73303e18 4000eb3 e60 System.String 0 shared static s_thisAppDomainsIsapiAppId >> Domain:Value 01f81230:NotInit 1f443310:024b0100 1e2d62c0:2f12c534 01fc1b88:300febe0 51063e70:039b9f00 << 7330f91c 4000eb4 c84 System.Boolean 1 shared static s_StopProcessingCalled >> Domain:Value 01f81230:NotInit 1f443310:0 1e2d62c0:0 01fc1b88:0 51063e70:0 << 7330f91c 4000eb5 c85 System.Boolean 1 shared static s_InitializationCompleted >> Domain:Value 01f81230:NotInit 1f443310:1 1e2d62c0:1 01fc1b88:1 51063e70:1 << 733041b8 4000eb6 e64 System.Object 0 shared static _delegatelock >> Domain:Value 01f81230:NotInit 1f443310:024c4990 1e2d62c0:4209fc50 01fc1b88:3016e73c 51063e70:3e92e32c << 7330560c 4000eb7 c68 System.Int32 1 shared static _inIndicateCompletionCount >> Domain:Value 01f81230:NotInit 1f443310:2 1e2d62c0:1 01fc1b88:1 51063e70:5 << 73302b8c 4000eb8 c6c System.IntPtr 1 shared static _asyncCompletionDelegatePointer >> Domain:Value 01f81230:NotInit 1f443310:1b016186 1e2d62c0:1b016d5e 01fc1b88:1b018b16 51063e70:1b018d96 << 6da6f6b0 4000eb9 e68 ...ompletionDelegate 0 shared static _asyncCompletionDelegate >> Domain:Value 01f81230:NotInit 1f443310:025ca294 1e2d62c0:0e370f7c 01fc1b88:3ccd512c 51063e70:5d41cac0 << 73302b8c 4000eba c70 System.IntPtr 1 shared static _asyncDisconnectNotificationDelegatePointer >> Domain:Value 01f81230:NotInit 1f443310:1b016276 1e2d62c0:1b016a3e 01fc1b88:1b018a4e 51063e70:1b0188e6 << 6da6f714 4000ebb e6c ...ificationDelegate 0 shared static _asyncDisconnectNotificationDelegate >> Domain:Value 01f81230:NotInit 1f443310:025ca2b4 1e2d62c0:0e370f9c 01fc1b88:3ccd514c 51063e70:5d41cae0 << 73302b8c 4000ebc c74 System.IntPtr 1 shared static _executeDelegatePointer >> Domain:Value 01f81230:NotInit 1f443310:1b0161fe 1e2d62c0:1b016a66 01fc1b88:1b0189fe 51063e70:1b018bb6 << 6da6f778 4000ebd e70 ...eFunctionDelegate 0 shared static _executeDelegate >> Domain:Value 01f81230:NotInit 1f443310:025ca2d4 1e2d62c0:0e370fbc 01fc1b88:3ccd516c 51063e70:5d41cb00 << 73302b8c 4000ebe c78 System.IntPtr 1 shared static _disposeDelegatePointer >> Domain:Value 01f81230:NotInit 1f443310:1b016226 1e2d62c0:1b016f16 01fc1b88:1b018ac6 51063e70:1b018ca6 << 6da6f7dc 4000ebf e74 ...eFunctionDelegate 0 shared static _disposeDelegate >> Domain:Value 01f81230:NotInit 1f443310:025ca2f4 1e2d62c0:0e370fdc 01fc1b88:3ccd518c 51063e70:5d41cb20 << 73302b8c 4000ec0 c7c System.IntPtr 1 shared static _roleDelegatePointer >> Domain:Value 01f81230:NotInit 1f443310:1b01624e 1e2d62c0:1b016b56 01fc1b88:1b018bde 51063e70:1b018c06 << 6da6f840 4000ec1 e78 ...eFunctionDelegate 0 shared static _roleDelegate >> Domain:Value 01f81230:NotInit 1f443310:025ca314 1e2d62c0:0e370ffc 01fc1b88:3ccd51ac 51063e70:5d41cb40 << 73302b8c 4000ec2 c80 System.IntPtr 1 shared static _principalDelegatePointer >> Domain:Value 01f81230:NotInit 1f443310:1b01615e 1e2d62c0:1b016b06 01fc1b88:1b018aee 51063e70:1b018cce << 6da6f8a4 4000ec3 e7c ...lFunctionDelegate 0 shared static _principalDelegate >> Domain:Value 01f81230:NotInit 1f443310:025ca334 1e2d62c0:0e37101c 01fc1b88:3ccd51cc 51063e70:5d41cb60 <<
….interpretace výstupu je zde již zřejmá, stejné jako u !DumpObj.