我不确定如何进行调试。我有一个完全由托管代码组成的 C# 程序,在 .NET 4.5 中运行。运行一段时间后,在某个看似随机的时间,我收到一条错误消息“mscorlib.dll 中发生'System.AccessViolationException'类型的未处理异常”。因为我是从 Visual Studio (2012) 运行它,所以我单击“break”并看到以下调用堆栈:
mscorlib.dll!System.Threading._IOCompletionCallback.PerformIOCompletionCallback(uint errorCode, uint numBytes, System.Threading.NativeOverlapped* pOVERLAP) + 0x47 bytes
[Native to Managed Transition]
ntdll.dll!_NtRequestWaitReplyPort@12() + 0xc bytes
kernel32.dll!_ConsoleClientCallServer@16() + 0x4f bytes
kernel32.dll!_GetConsoleLangId@4() + 0x2b bytes
kernel32.dll!_SetTEBLangID@0() + 0xf bytes
KernelBase.dll!_GetModuleHandleForUnicodeString@4() + 0x22 bytes
mdnsNSP.dll!7177aa48()
[Frames below may be incorrect and/or missing, no symbols loaded for mdnsNSP.dll]
mdnsNSP.dll!71775b06()
mdnsNSP.dll!71774ded()
mdnsNSP.dll!71774e8c()
bcryptprimitives.dll!746d1159()
bcryptprimitives.dll!746d1137()
ntdll.dll!_LdrpCallInitRoutine@16() + 0x14 bytes
ntdll.dll!_NtTestAlert@0() + 0xc bytes
ntdll.dll!_NtContinue@8() + 0xc bytes
ntdll.dll!_LdrInitializeThunk@8() + 0x1a bytes
我注意到的一件有趣的事情是调用堆栈中的任何内容都不是我的代码。
你会建议我使用什么策略来找到问题的路径?或者您是否遇到过类似的问题并有什么提示?
由于异常似乎不包括我的代码,我不知道要包括哪些信息有助于回答问题,但问我是否还有其他需要包括的信息。
由于错误可能与 IO 相关(因为 PerformIOCompletionCallback 位于堆栈顶部),这是此应用程序执行的典型 IO 任务的列表:
- TcpListener.AcceptTcpClientAsync
- NetworkStream.Write/BeginRead/EndRead
- SqlCommand.BeginExecuteReader/EndExecuteReader
- StreamWriter.WriteLine
其他注意事项:
- 它似乎是大致可重复的 - 我在同一个地方(PerformIOCompletionCallback)得到同样的错误,但必须等待不同的时间才能得到它(以分钟为单位)。
- 我不认为我可以制作一个可靠地突出问题的小程序。我的程序在遇到此错误之前处理了数千个类似的 IO 操作。
编辑:
根据@Kevin 的建议,即 Mdnsnsp.dll 来自 Bonjour,我卸载了 Bonjour 并再次尝试。异常仍然存在,但调用堆栈更清晰:
mscorlib.dll!System.Threading._IOCompletionCallback.PerformIOCompletionCallback(uint errorCode, uint numBytes, System.Threading.NativeOverlapped* pOVERLAP) + 0x47 bytes
[Native to Managed Transition]
kernel32.dll!@BaseThreadInitThunk@12() + 0x12 bytes
ntdll.dll!___RtlUserThreadStart@8() + 0x27 bytes
ntdll.dll!__RtlUserThreadStart@8() + 0x1b bytes
我假设 Bonjour 安装程序为网络流量安装了一些良性钩子 DLL,但卸载它并没有解决问题。
编辑:
我已经使用较慢的“安全”等效项临时重新编码了我的所有unsafe
功能,以消除它作为嫌疑人。现在应用程序中的所有程序集都没有使用不安全开关进行编译。问题仍然存在。重申一下,我现在在此应用程序中没有不安全代码、本机代码和 P/Invoke 调用(在用户代码中),但我仍然遇到AccessViolationException
上述情况。