找到System.AccessViolationException的原因

我们的应用程序经历了奇怪的致命System.AccessViolationException。 我们看到这些因为我们已经配置了AppDomain.CurrentDomain.UnhandledException事件来记录exception。

Exception: System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt. at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg) at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData) at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context) at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context) at System.Windows.Forms.Application.Run(Form mainForm) at Bootstrap.Run() in e:\build-dir\src\Bootstrap.cs:line 25 

除了“尝试读取或写入受保护的内存”之外,exception本身似乎不包含任何其他信息。这通常表明其他内存已损坏。

  • 我们现在可以采取哪些步骤来解决问题?
  • 有没有办法确定导致崩溃的非法地址或指针值?
  • 我们可以找出导致问题的本机库代码吗?
  • 我们可以启用更多的调试/跟踪吗?

UPDATE

  • 这可能是由早期的非线程安全使用WinForms API引起的吗?

您遇到的情况完全等同于“程序遇到问题并且现在将关闭”,除非它被.NET运行时捕获,而不是操作系统。

查看堆栈跟踪,它不会被您的代码触发,这使我认为它来自您正在使用的库或自定义控件生成的工作线程。

跟踪这样的事情的唯一方法是在调试器下运行本机库,调试器应该在访问冲突到CLR层之前捕获它。 这可能很容易或很难。

如果本机代码是您自己的项目,那么设置它的最简单方法是将.NET项目和C ++项目放在同一个解决方案中,并确保.NET项目引用C ++项目。 如果您发布有关您的环境的更多详细信息,我可能会提供更具体的建议。

堆栈跟踪指向本机调度信使的MSG参数中的错误数据。 您是否尝试从Microsoft加载符号并检查该堆栈跟踪的参数。

如果不了解您的ui上的控件以及您连接的任何事件,将很难确定问题究竟是什么。

我有一个类似的问题,不像@BartRead,始终如一。 对我来说,一些CLI代码在一个简单的Windows窗体应用程序中运行良好,但是当我把它放在一个larager插件生态系统(multithreading)中时,消息需要使用Application.Run或Application.DoEvents。 如果您可以访问正在抽取的代码,那么最好的选择(对我有用)就是在保持function的同时注释掉越来越多的代码。 事实certificate我没有GC :: Alloc一个回调/委托,虽然固定并仍然引用已经在内存中移动或直接标记为收集。

如果您使用GC Alloc,请务必自行清理!

我使用ADO执行存储过程时遇到此问题。 这个错误有两个原因:

  1. 连接字符串错误。
  2. 参数类型miss-match(传入db-int32或long为nvarchar(10)更短)