WinDbg+SOS: Prozkoumávání statických fieldů a statických tříd

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.

Napsat komentář

Vyplňte detaily níže nebo klikněte na ikonu pro přihlášení:

WordPress.com Logo

Komentujete pomocí vašeho WordPress.com účtu. Log Out / Změnit )

Twitter picture

Komentujete pomocí vašeho Twitter účtu. Log Out / Změnit )

Facebook photo

Komentujete pomocí vašeho Facebook účtu. Log Out / Změnit )

Google+ photo

Komentujete pomocí vašeho Google+ účtu. Log Out / Změnit )

Připojování k %s