如何在 WinDbg 中查看 .NET 并发集合?
How to view .NET concurrent collections in WinDbg?
有没有什么有效的方法可以查看 ConcurrentQueue
、ConcurrentDictionary
、...、BlockingCollection
等并发集合的内容?
有一个不错的 extension netext,但这只能转储旧的和好的 Dictionary<..>
和 Hashtable
。
老实说,我很惊讶我没有找到对此的任何支持,因为在实例中遍历 buckets、tails & heads 是一种非常缓慢的方法。
SOSEX' 如果您有支持 DML 的 WinDbg 版本,!mdt
命令似乎还不错,因为您随后可以单击 link 来显示和展开数组
ConcurrentQueue(注意m_array
是可点击的link):
0:000> !mdt 000007fe959f4770 0000000002614660 -r:5
0000000002614660 (System.Collections.Concurrent.ConcurrentQueue`1[[System.String, mscorlib]])
m_head:0000000002614690 (System.Collections.Concurrent.ConcurrentQueue`1+Segment[[System.String, mscorlib]])
m_array:00000000026146d0 (System.String[], Elements: 32)
m_state:00000000026147e8 (System.Collections.Concurrent.VolatileBool[], Elements: 32, ElementMT=000007fef41022d8)
m_next:NULL (System.Collections.Concurrent.ConcurrentQueue`1+Segment[[System.__Canon, mscorlib]])
m_index:0x0 (System.Int64)
m_low:0x0 (System.Int32)
m_high:0x9 (System.Int32)
m_source:0000000002614660 (System.Collections.Concurrent.ConcurrentQueue`1[[System.String, mscorlib]])
<RECURSIVE>
m_tail:0000000002614690 (System.Collections.Concurrent.ConcurrentQueue`1+Segment[[System.String, mscorlib]])
m_array:00000000026146d0 (System.String[], Elements: 32)
m_state:00000000026147e8 (System.Collections.Concurrent.VolatileBool[], Elements: 32, ElementMT=000007fef41022d8)
m_next:NULL (System.Collections.Concurrent.ConcurrentQueue`1+Segment[[System.__Canon, mscorlib]])
m_index:0x0 (System.Int64)
m_low:0x0 (System.Int32)
m_high:0x9 (System.Int32)
m_source:0000000002614660 (System.Collections.Concurrent.ConcurrentQueue`1[[System.String, mscorlib]])
<RECURSIVE>
m_serializationArray:NULL (System.__Canon[])
m_numSnapshotTakers:0x0 (System.Int32)
0:000> !mdt 00000000026146d0
00000000026146d0 (System.String[], Elements: 32)
expand all 32 items <--- DML Link
0:000> !mdt -e:2 00000000026146d0
00000000026146d0 (System.String[], Elements: 32)
[0] 0000000002617508 "Hello WinDbg 0"
[1] 0000000002617670 "Hello WinDbg 1"
[2] 00000000026177d8 "Hello WinDbg 2"
[3] 0000000002617940 "Hello WinDbg 3"
[4] 0000000002617aa8 "Hello WinDbg 4"
[5] 0000000002617c10 "Hello WinDbg 5"
[6] 0000000002617d78 "Hello WinDbg 6"
[7] 0000000002617ee0 "Hello WinDbg 7"
[8] 0000000002618048 "Hello WinDbg 8"
[9] 00000000026181b0 "Hello WinDbg 9"
ConcurrentDictionary(注意m_buckets
是可点击的link)
0:000> !mdt 0000000002614820 -r:6
0000000002614820 (System.Collections.Concurrent.ConcurrentDictionary`2[[System.String, mscorlib],[System.String, mscorlib]])
m_tables:0000000002614eb0 (System.Collections.Concurrent.ConcurrentDictionary`2+Tables[[System.String, mscorlib],[System.String, mscorlib]])
m_buckets:0000000002614d98 (System.Collections.Concurrent.ConcurrentDictionary`2+Node[[System.String, mscorlib],[System.String, mscorlib]][], Elements: 32)
m_locks:00000000026148e8 (System.Object[], Elements: 32)
m_countPerLock:0000000002614d00 (System.Int32[], Elements: 32)
m_comparer:00000000026148d0 (System.Collections.Generic.GenericEqualityComparer`1[[System.String, mscorlib]])
m_comparer:NULL (System.Collections.Generic.IEqualityComparer`1[[System.__Canon, mscorlib]])
m_growLockArray:true (System.Boolean)
m_keyRehashCount:0x0 (System.Int32)
m_budget:0x1 (System.Int32)
m_serializationArray:NULL (System.Collections.Generic.KeyValuePair`2[[System.__Canon, mscorlib],[System.__Canon, mscorlib]][])
m_serializationConcurrencyLevel:0x0 (System.Int32)
m_serializationCapacity:0x0 (System.Int32)
0:000> !mdt 0000000002614d98
0000000002614d98 (System.Collections.Concurrent.ConcurrentDictionary`2+Node[[System.String, mscorlib],[System.String, mscorlib]][], Elements: 32)
expand all 32 items <--- DML Link
0:000> !mdt -e:2 0000000002614d98
0000000002614d98 (System.Collections.Concurrent.ConcurrentDictionary`2+Node[[System.String, mscorlib],[System.String, mscorlib]][], Elements: 32)
[...]
[18] 0000000002618148 (System.Collections.Concurrent.ConcurrentDictionary`2+Node[[System.String, mscorlib],[System.String, mscorlib]])
m_key:00000000026180b8 (System.String) Length=7, String="Hello 8"
m_value:0000000002618118 (System.String) Length=8, String="WinDbg 8"
m_next:NULL (System.Collections.Concurrent.ConcurrentDictionary`2+Node[[System.__Canon, mscorlib],[System.__Canon, mscorlib]])
m_hashcode:0xd0fe55d2 (System.Int32)
[19] 00000000026182b0 (System.Collections.Concurrent.ConcurrentDictionary`2+Node[[System.String, mscorlib],[System.String, mscorlib]])
m_key:0000000002618220 (System.String) Length=7, String="Hello 9"
m_value:0000000002618280 (System.String) Length=8, String="WinDbg 9"
m_next:NULL (System.Collections.Concurrent.ConcurrentDictionary`2+Node[[System.__Canon, mscorlib],[System.__Canon, mscorlib]])
m_hashcode:0xd0fe55d3 (System.Int32)
感谢 Mikhail Polgun 的代码贡献,NetExt 现在正在实施 !wconcurrentdict。
!wconcurrentdict <address>
<address> - Address of the dictionary.
Examples:
Dumps a dictionary
------------------------
0:000> wconcurrentdict 00000001557d3920
Items : 1
[0]:==============================================
System.__Canon key = 00000001557d2a70 CompilerVersion
System.__Canon value = 00000001557d2aa8 v2.0
在此处下载 NetExt 的 zip:https://github.com/rodneyviana/netext/tree/master/Binaries
有没有什么有效的方法可以查看 ConcurrentQueue
、ConcurrentDictionary
、...、BlockingCollection
等并发集合的内容?
有一个不错的 extension netext,但这只能转储旧的和好的 Dictionary<..>
和 Hashtable
。
老实说,我很惊讶我没有找到对此的任何支持,因为在实例中遍历 buckets、tails & heads 是一种非常缓慢的方法。
SOSEX' 如果您有支持 DML 的 WinDbg 版本,!mdt
命令似乎还不错,因为您随后可以单击 link 来显示和展开数组
ConcurrentQueue(注意m_array
是可点击的link):
0:000> !mdt 000007fe959f4770 0000000002614660 -r:5
0000000002614660 (System.Collections.Concurrent.ConcurrentQueue`1[[System.String, mscorlib]])
m_head:0000000002614690 (System.Collections.Concurrent.ConcurrentQueue`1+Segment[[System.String, mscorlib]])
m_array:00000000026146d0 (System.String[], Elements: 32)
m_state:00000000026147e8 (System.Collections.Concurrent.VolatileBool[], Elements: 32, ElementMT=000007fef41022d8)
m_next:NULL (System.Collections.Concurrent.ConcurrentQueue`1+Segment[[System.__Canon, mscorlib]])
m_index:0x0 (System.Int64)
m_low:0x0 (System.Int32)
m_high:0x9 (System.Int32)
m_source:0000000002614660 (System.Collections.Concurrent.ConcurrentQueue`1[[System.String, mscorlib]])
<RECURSIVE>
m_tail:0000000002614690 (System.Collections.Concurrent.ConcurrentQueue`1+Segment[[System.String, mscorlib]])
m_array:00000000026146d0 (System.String[], Elements: 32)
m_state:00000000026147e8 (System.Collections.Concurrent.VolatileBool[], Elements: 32, ElementMT=000007fef41022d8)
m_next:NULL (System.Collections.Concurrent.ConcurrentQueue`1+Segment[[System.__Canon, mscorlib]])
m_index:0x0 (System.Int64)
m_low:0x0 (System.Int32)
m_high:0x9 (System.Int32)
m_source:0000000002614660 (System.Collections.Concurrent.ConcurrentQueue`1[[System.String, mscorlib]])
<RECURSIVE>
m_serializationArray:NULL (System.__Canon[])
m_numSnapshotTakers:0x0 (System.Int32)
0:000> !mdt 00000000026146d0
00000000026146d0 (System.String[], Elements: 32)
expand all 32 items <--- DML Link
0:000> !mdt -e:2 00000000026146d0
00000000026146d0 (System.String[], Elements: 32)
[0] 0000000002617508 "Hello WinDbg 0"
[1] 0000000002617670 "Hello WinDbg 1"
[2] 00000000026177d8 "Hello WinDbg 2"
[3] 0000000002617940 "Hello WinDbg 3"
[4] 0000000002617aa8 "Hello WinDbg 4"
[5] 0000000002617c10 "Hello WinDbg 5"
[6] 0000000002617d78 "Hello WinDbg 6"
[7] 0000000002617ee0 "Hello WinDbg 7"
[8] 0000000002618048 "Hello WinDbg 8"
[9] 00000000026181b0 "Hello WinDbg 9"
ConcurrentDictionary(注意m_buckets
是可点击的link)
0:000> !mdt 0000000002614820 -r:6
0000000002614820 (System.Collections.Concurrent.ConcurrentDictionary`2[[System.String, mscorlib],[System.String, mscorlib]])
m_tables:0000000002614eb0 (System.Collections.Concurrent.ConcurrentDictionary`2+Tables[[System.String, mscorlib],[System.String, mscorlib]])
m_buckets:0000000002614d98 (System.Collections.Concurrent.ConcurrentDictionary`2+Node[[System.String, mscorlib],[System.String, mscorlib]][], Elements: 32)
m_locks:00000000026148e8 (System.Object[], Elements: 32)
m_countPerLock:0000000002614d00 (System.Int32[], Elements: 32)
m_comparer:00000000026148d0 (System.Collections.Generic.GenericEqualityComparer`1[[System.String, mscorlib]])
m_comparer:NULL (System.Collections.Generic.IEqualityComparer`1[[System.__Canon, mscorlib]])
m_growLockArray:true (System.Boolean)
m_keyRehashCount:0x0 (System.Int32)
m_budget:0x1 (System.Int32)
m_serializationArray:NULL (System.Collections.Generic.KeyValuePair`2[[System.__Canon, mscorlib],[System.__Canon, mscorlib]][])
m_serializationConcurrencyLevel:0x0 (System.Int32)
m_serializationCapacity:0x0 (System.Int32)
0:000> !mdt 0000000002614d98
0000000002614d98 (System.Collections.Concurrent.ConcurrentDictionary`2+Node[[System.String, mscorlib],[System.String, mscorlib]][], Elements: 32)
expand all 32 items <--- DML Link
0:000> !mdt -e:2 0000000002614d98
0000000002614d98 (System.Collections.Concurrent.ConcurrentDictionary`2+Node[[System.String, mscorlib],[System.String, mscorlib]][], Elements: 32)
[...]
[18] 0000000002618148 (System.Collections.Concurrent.ConcurrentDictionary`2+Node[[System.String, mscorlib],[System.String, mscorlib]])
m_key:00000000026180b8 (System.String) Length=7, String="Hello 8"
m_value:0000000002618118 (System.String) Length=8, String="WinDbg 8"
m_next:NULL (System.Collections.Concurrent.ConcurrentDictionary`2+Node[[System.__Canon, mscorlib],[System.__Canon, mscorlib]])
m_hashcode:0xd0fe55d2 (System.Int32)
[19] 00000000026182b0 (System.Collections.Concurrent.ConcurrentDictionary`2+Node[[System.String, mscorlib],[System.String, mscorlib]])
m_key:0000000002618220 (System.String) Length=7, String="Hello 9"
m_value:0000000002618280 (System.String) Length=8, String="WinDbg 9"
m_next:NULL (System.Collections.Concurrent.ConcurrentDictionary`2+Node[[System.__Canon, mscorlib],[System.__Canon, mscorlib]])
m_hashcode:0xd0fe55d3 (System.Int32)
感谢 Mikhail Polgun 的代码贡献,NetExt 现在正在实施 !wconcurrentdict。
!wconcurrentdict <address>
<address> - Address of the dictionary.
Examples:
Dumps a dictionary
------------------------
0:000> wconcurrentdict 00000001557d3920
Items : 1
[0]:==============================================
System.__Canon key = 00000001557d2a70 CompilerVersion
System.__Canon value = 00000001557d2aa8 v2.0
在此处下载 NetExt 的 zip:https://github.com/rodneyviana/netext/tree/master/Binaries