Windbg使用TryGetValue从字典中获取值

时间:2015-03-12 21:47:53

标签: c# dictionary windbg

我有一个来自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)到输出,而指针没有列在“参数”部分。
  3. 提前致谢!

1 个答案:

答案 0 :(得分:3)

您还没有共享源代码,而且您还没有写过您是否使用静态词典,所以我假设您不是。但是你怀疑你的词典是在线程之间共享的 - 让我们发现它。当您处于方法中间或代码高度优化时,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 - 因为你可以看到它也在堆栈中。