windbg - 调试“已添加具有相同键的项目”异常
问题描述
当我收到“已添加具有相同密钥的项目”异常时,我对我的应用程序进行了崩溃转储。我需要帮助找出导致此异常的对象。我可以打印异常,但不知道如何找到导致异常的确切键。
解决方案
这可能是您的状态:
[...]
(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");
}
}
}