代码中的访问冲突不是我的

时间:2013-01-17 19:08:13

标签: c# .net access-violation

我不知道如何调试这个。我有一个完全由托管代码组成的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

3 个答案:

答案 0 :(得分:3)

由于导致错误的PerformIOCompletionCallback,我会查看你的异步IO调用。

  • TcpListener.AcceptTcpClientAsync
  • NetworkStream.Write /的BeginRead / EndRead
  • SqlCommand.BeginExecuteReader / EndExecuteReader

错误看起来正在发生,因为已注册的句柄不再有效。由于它发生在托管代码中,原因将来自托管对象,而不是来自第三方本机DLL。

答案 1 :(得分:2)

不知道它是否可以帮助你,但看起来我们几年前遇到过类似的问题。我记得我们的调查指向其他程序中的dll - 我们发现内存访问违规可能是由防病毒软件(在我们的例子中是NOD32),防火墙或网络嗅探器/流量控制器引起的。

尝试检查应用程序日志(控制面板 - >系统和安全性 - >管理工具 - >事件查看器),查看由上述应用程序引起的错误。如果其他程序出现问题,请尝试禁用/卸载它,并再次检查程序中是否仍出现崩溃。

UPD 您是否尝试在干净的测试环境中重现此问题?

答案 2 :(得分:1)

您可以使用debugdiag查看导致计算机上的AccessViolationException的原因。为进程配置崩溃规则并检查转储和日志文件。我希望你能以这种方式获得有关这一主题的更多信息。另外一定要让您的机器运行最新的Windows更新bcos我有一个类似的问题,已在CLR版本的安全更新中解决。