Windbg 使用 TryGetValue 从字典中获取值
Windbg get value from dictionary using TryGetValue
我有一个 IIS 进程的转储,该进程消耗了将近 100% 的 CPU。我 运行 windbg 和 运行 宁 !runaway
命令后,我发现顶部线程都卡在字典 FindEntry(System.__Canon)
命令中。这些线程之一的堆栈开始于:
0:043> !clrstack -p
OS Thread Id: 0x1740 (43)
Child SP IP Call Site
0000008646eecc78 00007ff810530c8a [RedirectedThreadFrame: 0000008646eecc78]
0000008646eecd10 00007ffffe420ccd System.Collections.Generic.Dictionary`2[[System.__Canon, mscorlib],[System.__Canon, mscorlib]].FindEntry(System.__Canon)
PARAMETERS:
this = <no data>
key = <no data>
0000008646eecd80 00007ffffe422ed4 System.Collections.Generic.Dictionary`2[[System.__Canon, mscorlib],[System.__Canon, mscorlib]].TryGetValue(System.__Canon, System.__Canon ByRef)
PARAMETERS:
this = <no data>
key = <no data>
value = <no data>
我怀疑我的问题与 this one 类似,但我需要更多证据才能得出结论。为此,我希望我可以获得有关字典的值或任何其他信息。查看这段代码,与网上的大多数教程有两点不同:
- 参数显示为
System.__Canon
。这是什么意思?
- 如何从
TryGetValue
中获取值,因为它只有对输出的引用 (ByRef),并且指针未在 "parameters" 部分中列出。
提前致谢!
你没有分享源代码,也没有写你是否在使用静态字典,所以我假设你没有。但是您怀疑您的词典在线程之间共享 - 让我们找出来。 CLRStack
当您处于方法中间或代码高度优化时,经常找不到参数。另一个非常有用的 SOS 命令是 !DumpStackObjects
或 !dso
。它只是转储堆栈上的所有托管对象。您可能会在那里找到您的关键值(除非它是基本类型 - 那么事情会变得更加复杂,我需要更多信息来帮助您)。示例输出可能如下所示:
OS Thread Id: 0x1520 (0)
ESP/REG Object Name
ecx 020e21b4 System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.String, mscorlib]]
edx 020e218c System.String k1
esi 020e21b4 System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.String, mscorlib]]
005BED6C 020e1228 System.String
005BED70 020e218c System.String k1
005BED78 020e45a4 System.IO.TextReader+SyncTextReader
005BED80 020e21b4 System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.String, mscorlib]]
005BED90 020e217c System.Object[] (System.String[])
005BEDA0 020e1228 System.String
005BEDA4 020e21b4 System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.String, mscorlib]]
005BEDA8 020e21b4 System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.String, mscorlib]]
005BEDAC 020e21b4 System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.String, mscorlib]]
005BEDB8 020e21a0 System.String v1
005BEDBC 020e217c System.Object[] (System.String[])
005BEE40 020e217c System.Object[] (System.String[])
005BEFA4 020e217c System.Object[] (System.String[])
005BEFD4 020e217c System.Object[] (System.String[])
注意字典在列表中。 运行 此命令针对每个线程并验证它们是否共享字典地址。 System.__Canon
不是您应该担心的 - 它只是泛型类型 (http://referencesource.microsoft.com/#mscorlib/system/object.cs,a210e11a9e5f2deb) 中的一个占位符。在上面的输出中,我有一个 Dictionary<String,String>
实例并且正在寻找 k1 - 如您所见,它也在堆栈上。
我有一个 IIS 进程的转储,该进程消耗了将近 100% 的 CPU。我 运行 windbg 和 运行 宁 !runaway
命令后,我发现顶部线程都卡在字典 FindEntry(System.__Canon)
命令中。这些线程之一的堆栈开始于:
0:043> !clrstack -p
OS Thread Id: 0x1740 (43)
Child SP IP Call Site
0000008646eecc78 00007ff810530c8a [RedirectedThreadFrame: 0000008646eecc78]
0000008646eecd10 00007ffffe420ccd System.Collections.Generic.Dictionary`2[[System.__Canon, mscorlib],[System.__Canon, mscorlib]].FindEntry(System.__Canon)
PARAMETERS:
this = <no data>
key = <no data>
0000008646eecd80 00007ffffe422ed4 System.Collections.Generic.Dictionary`2[[System.__Canon, mscorlib],[System.__Canon, mscorlib]].TryGetValue(System.__Canon, System.__Canon ByRef)
PARAMETERS:
this = <no data>
key = <no data>
value = <no data>
我怀疑我的问题与 this one 类似,但我需要更多证据才能得出结论。为此,我希望我可以获得有关字典的值或任何其他信息。查看这段代码,与网上的大多数教程有两点不同:
- 参数显示为
System.__Canon
。这是什么意思? - 如何从
TryGetValue
中获取值,因为它只有对输出的引用 (ByRef),并且指针未在 "parameters" 部分中列出。
提前致谢!
你没有分享源代码,也没有写你是否在使用静态字典,所以我假设你没有。但是您怀疑您的词典在线程之间共享 - 让我们找出来。 CLRStack
当您处于方法中间或代码高度优化时,经常找不到参数。另一个非常有用的 SOS 命令是 !DumpStackObjects
或 !dso
。它只是转储堆栈上的所有托管对象。您可能会在那里找到您的关键值(除非它是基本类型 - 那么事情会变得更加复杂,我需要更多信息来帮助您)。示例输出可能如下所示:
OS Thread Id: 0x1520 (0)
ESP/REG Object Name
ecx 020e21b4 System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.String, mscorlib]]
edx 020e218c System.String k1
esi 020e21b4 System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.String, mscorlib]]
005BED6C 020e1228 System.String
005BED70 020e218c System.String k1
005BED78 020e45a4 System.IO.TextReader+SyncTextReader
005BED80 020e21b4 System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.String, mscorlib]]
005BED90 020e217c System.Object[] (System.String[])
005BEDA0 020e1228 System.String
005BEDA4 020e21b4 System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.String, mscorlib]]
005BEDA8 020e21b4 System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.String, mscorlib]]
005BEDAC 020e21b4 System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.String, mscorlib]]
005BEDB8 020e21a0 System.String v1
005BEDBC 020e217c System.Object[] (System.String[])
005BEE40 020e217c System.Object[] (System.String[])
005BEFA4 020e217c System.Object[] (System.String[])
005BEFD4 020e217c System.Object[] (System.String[])
注意字典在列表中。 运行 此命令针对每个线程并验证它们是否共享字典地址。 System.__Canon
不是您应该担心的 - 它只是泛型类型 (http://referencesource.microsoft.com/#mscorlib/system/object.cs,a210e11a9e5f2deb) 中的一个占位符。在上面的输出中,我有一个 Dictionary<String,String>
实例并且正在寻找 k1 - 如您所见,它也在堆栈上。