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 类似,但我需要更多证据才能得出结论。为此,我希望我可以获得有关字典的值或任何其他信息。查看这段代码,与网上的大多数教程有两点不同:

  1. 参数显示为System.__Canon。这是什么意思?
  2. 如何从 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 - 如您所见,它也在堆栈上。