【问题标题】:Debug "An item with the same key has already been added" exception调试“已添加具有相同键的项目”异常
【发布时间】:2019-08-10 17:01:22
【问题描述】:

当我收到“已添加具有相同密钥的项目”异常时,我对我的应用程序进行了故障转储。我需要帮助找出导致此异常的对象。我可以打印异常,但不知道如何找到导致异常的确切键。

【问题讨论】:

    标签: windbg


    【解决方案1】:

    这可能是你的状态:

    [...]
    (3250.7ec): CLR exception - code e0434352 (!!! second chance !!!)
    [...]
    0:000> .loadby sos clr
    0:000> !pe
    Exception object: 030c31e8
    Exception type:   System.ArgumentException
    Message:          An item with the same key has already been added.
    InnerException:   <none>
    StackTrace (generated):
        SP       IP       Function
        010FEE1C 6045F705 mscorlib_ni!System.ThrowHelper.ThrowArgumentException(System.ExceptionResource)+0x35
        010FEE2C 609410C7 mscorlib_ni!System.Collections.Generic.Dictionary`2[[System.__Canon, mscorlib],[System.__Canon, mscorlib]].Insert(System.__Canon, System.__Canon, Boolean)+0xc6af67
        010FEE60 5FD4B310 mscorlib_ni!System.Collections.Generic.Dictionary`2[[System.__Canon, mscorlib],[System.__Canon, mscorlib]].Add(System.__Canon, System.__Canon)+0x10
        010FEE68 017004F5 KeyAlreadyAdded!KeyAlreadyAdded.Program.Main()+0x45
    [...]
    

    在本机调用堆栈中,您可以再次看到对Dictionary.Add() 的调用,但带有帧号的附加信息:

    0:000> k
     # ChildEBP RetAddr  
    00 010fecb0 618fac03 KERNELBASE!RaiseException+0x62
    01 010fed4c 618fae08 clr!RaiseTheExceptionInternalOnly+0x27c
    02 010fee14 6045f705 clr!IL_Throw+0x141
    03 010fee24 609410c7 mscorlib_ni!System.ThrowHelper.ThrowArgumentException(System.ExceptionResource)$##6000335+0x35
    04 010fee50 5fd4b310 mscorlib_ni![COLD] System.Collections.Generic.Dictionary`2[System.__Canon,System.__Canon].Insert(System.__Canon, System.__Canon, Boolean)$##6003922+0x87
    05 010fee68 6181ebe6 mscorlib_ni!System.Collections.Generic.Dictionary`2[System.__Canon,System.__Canon].Add(System.__Canon, System.__Canon)$##6003915+0x10
    [...]
    

    Insert()方法中,可以使用ebx寄存器获取密钥:

    0:000> .frame /r 4
    04 010fee50 5fd4b310 mscorlib_ni![COLD] System.Collections.Generic.Dictionary`2[System.__Canon,System.__Canon].Insert(System.__Canon, System.__Canon, Boolean)$##6003922+0x87
    eax=010fec58 ebx=030c2364 ecx=00000005 edx=00000000 esi=030c23b0 edi=030c2364
    [...]
    
    0:000> !do 030c2364
    Name:        System.String
    MethodTable: 5fdefd60
    EEClass:     5f9c4e90
    Size:        22(0x16) bytes
    File:        C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll
    String:      this
    [...]
    

    所以在这种情况下,添加的重复键是字符串“this”。代码如下:

    using System.Collections.Generic;
    
    namespace KeyAlreadyAdded
    {
        class Program
        {
            static Dictionary<string, string> dict = new Dictionary<string, string> {{"this", "was already inside"}};
            static void Main()
            {
                dict.Add("that", "goes in easily");
                dict.Add("this", "however, causes a duplicate key exception");
            }
        }
    }
    

    【讨论】:

    • 如何找到字典的内容?
    猜你喜欢
    • 2011-06-18
    • 2014-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多