Using WinDbg and trying to debug a Silverlight application for memory leaks, I come across properties on my objects that are implemented as a DependencyProperty - and when I dump the object in the debugger (WinDbg) I can see the property - that is, I can see the actual static field.
How do I开发者_运维百科 see the actual value of the property?
This heavily relies on making assumptions about undocumented internals that may vary in other versions, but by way of example here's how to get the value of the Title property of a window in WPF with .NET 4, documented here so I can find it with Google again.
First, find the address of the value of System.Windows.Window.TitleProperty
:
0:000> !name2ee *!System.Windows.Window ... Module: 54b81000 Assembly: PresentationFramework.dll Token: 0200009c MethodTable: 54f06b54 EEClass: 54ba12bc <--- Remember this Name: System.Windows.Window ... 0:000> !DumpClass /d 54ba12bc <--- EEClass value from above ... 62887fec 40002f1 4cc ...ependencyProperty 0 static 020e724c TitleProperty ... ^^^^^^^^ Property object address
Now, get its GlobalIndex
, which is the bottom 16 bits of the _packedData
field:
0:000> !DumpObj /d 020e724c <--- Property object address from above ... 62a9c190 4001377 20 System.Int32 1 instance 262372 _packedData ... ^^^^^^ & 0xffff == 228
So 228 is the GlobalIndex
.
Now find the address of the window:
0:000> !name2ee *!Your.Window.Class.Name ... Module: 00122e9c Assembly: YourAssembly.exe Token: 020001fc MethodTable: 002a4068 <--- Remember this EEClass: 00297504 Name: Your.Window.Class.Name ... 0:000> !dumpheap -mt 002a4068 <--- Remember this Address MT Size 020e6b6c 002a4068 456 <--- If >1 object found, you must pick the right one. ...
The window is at 020e6b6c. The value you are looking for is somewhere in its _effectiveValues
array:
0:000> !DumpObj /d 020e6b6c ... 6288e394 4001359 10 ...ctiveValueEntry[] 0 instance 0912e08c _effectiveValues ... ^^^^^^^^ Array address 0:000> !DumpArray -details 0912e08c ... [18] 0912e124 Name: System.Windows.EffectiveValueEntry MethodTable: 6288978c EEClass: 627bda2c Size: 16(0x10) bytes File: C:\Windows\Microsoft.Net\assembly\GAC_MSIL\WindowsBase\v4.0_4.0.0.0__31bf3856ad364e35\WindowsBase.dll Fields: MT Field Offset Type VT Attr Value Name 57bcf568 40013a7 0 System.Object 0 instance 091df9c8 _value 57bd4798 40013a8 4 System.Int16 1 instance 228 _propertyIndex 62a9c360 40013a9 6 System.Int16 1 instance 27 _source ...
The array is sorted by the values of the _propertyIndex
fields (except for some empty entries at the end with _propertyIndex == -1
) so it is not hard to find the entry with _propertyIndex
228.
Finally, dump the corresponding _value
field:
0:000> !DumpObj /d 091df9c8 ... 57bcf568 40013c0 4 System.Object 0 instance 020f6228 _baseValue 57bcf568 40013c1 8 System.Object 0 instance 091df92c _expressionValue 57bcf568 40013c2 c System.Object 0 instance 00000000 _animatedValue 57bcf568 40013c3 10 System.Object 0 instance 00000000 _coercedValue ... 0:000> !DumpObj /d 020f6228 <--- From _baseValue, gives the binding expression ... Name: System.Windows.Data.BindingExpression ... 0:000> !DumpObj /d 091df92c <--- From _expressionValue, gives the actual value ... String: YOUR WINDOW TITLE ...
Woo hoo.
You should be able to get the value using the GetValue(PropertyName) method on the DependencyObject (which is required for it to have a Dependency Property). Not sure if that works in WinDbg. Tess Ferrandez mentions one tip with Dependency Properties but it doesn't give a true answer.
For a complete solution, try this step-by-step guide: http://georgelache.blogspot.ro/2012/04/steps-to-get-value-of-dependency.html
The example covers the case of obtaining the title of a window
!CLRStack -a
..
0000000000129270 000006442d6acf50 System.Windows.Window.InternalClose(Boolean, Boolean)
PARAMETERS:
this (0x0000000000129360) = 0x0000000011b59968
shutdown = <no data>
ignoreCancel = <no data>
LOCALS:
<no data>
<no data>
<no data>
...
0:000> !do 0x0000000011b59968
Name: GFW.Controls.View.ShellWindow MethodTable: 00000644805228b8 EEClass: 0000064480516240 Size: 832(0x340) bytes ...
00000644319b3708 40002d3 998 ...ependencyProperty 0 static 00000000115de6d8 TitleProperty 00000644319be898 4001323 20 ...ctiveValueEntry[] 0 instance 00000000154ff638 _effectiveValues ...
0:000> !do /d 00000000115de6d8
Name: System.Windows.DependencyProperty
MethodTable: 00000644319b3708
EEClass: 0000064431857550
Size: 88(0x58) bytes
File: C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\WindowsBase\v4.0_4.0.0.0__31bf3856ad364e35\WindowsBase.dll
Fields:
MT Field Offset Type VT Attr Value Name
00000644784c6960 400133c 8 System.String 0 instance 00000000111f6450 _name
00000644784c82e8 400133d 10 System.Type 0 instance 0000000011024538 _propertyType
00000644784c82e8 400133e 18 System.Type 0 instance 0000000011255ea8 _ownerType
00000644319b12a8 400133f 20 ....PropertyMetadata 0 instance 00000000115de678 _defaultMetadata
00000644319b1088 4001340 28 ...dateValueCallback 0 instance 00000000115de638 _validateValueCallback
00000644319be750 4001341 30 ...ndencyPropertyKey 0 instance 0000000000000000 _readOnlyKey
0000064431c147f8 4001342 40 System.Int32 1 instance 262462 _packedData
00000644319be408 4001343 48 ....InsertionSortMap 1 instance 00000000115de720 _metadataMap
00000644319b0fc8 4001344 38 ...erceValueCallback 0 instance 0000000000000000 _designerCoerceValueCallback
00000644784c5ab8 400133b 808 System.Object 0 static 000000001102f290 UnsetValue
00000644319bc6c0 4001345 800 ...ty, WindowsBase]] 1 static 0000000021033b88 RegisteredPropertyList
00000644784d1c28 4001346 810 ...ections.Hashtable 0 static 0000000011030aa8 PropertyFromName
00000644784cc848 4001347 5c8 System.Int32 1 static 1290 GlobalIndexCount
00000644784c5ab8 4001348 818 System.Object 0 static 00000000110407e8 Synchronized
00000644784c82e8 4001349 820 System.Type 0 static 0000000011040800 NullableType
GlobalIndex: Get the index of the property: 262462 & 0xFFFF (using Windows Calculator) = 318
!DumpArray -details 00000000154ff638
[31] 00000000154ff838
Name: System.Windows.EffectiveValueEntry
MethodTable: 00000644319b6120
EEClass: 0000064431858c90
Size: 32(0x20) bytes
File: C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\WindowsBase\v4.0_4.0.0.0__31bf3856ad364e35\WindowsBase.dll
Fields:
MT Field Offset Type VT Attr Value Name
00000644784c5ab8 400136e 0 System.Object 0 instance 0000000041dd7b88 _value
00000644784d0930 400136f 8 System.Int16 1 instance 318 _propertyIndex
0000064431c149b0 4001370 a System.Int16 1 instance 11 _source
0:000> !do /d 0000000041dd7b88
Name: System.String
MethodTable: 00000644784c6960
EEClass: 000006447804eec8
Size: 108(0x6c) bytes
File: C:\WINDOWS\Microsoft.Net\assembly\GAC_64\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll
String: My Window Title
精彩评论