2011-02-27 126 views
26

我们的应用程序遇到奇怪的致命System.AccessViolationException。我们看到了这些,因为我们配置了AppDomain.CurrentDomain.UnhandledException事件来记录异常。找到System.AccessViolationException的原因

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 

例外本身似乎并没有包含任何不是消息更多信息“尝试读取或写入受保护的内存。这通常是指示其他内存已损坏。”

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

UPDATE

  • 难道这由早期非线程使用的WinForms的API造成的?
+1

您是否尝试过上附加一个调试运行此,也有足够的符号加载给一个有用的callstack? – 2012-04-20 01:52:51

回答

5

您所遇到的与“程序遇到问题并将立即关闭”的确切等效,除非它被.NET运行时捕获,而不是被操作系统捕获。

看着堆栈跟踪,它并没有被你的代码触发,这让我认为它来自你正在使用的库或自定义控件产生的工作者线程。

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

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

+1

这不是一个工作线程,它在主UI线程上死掉。注意Application.Run() – 2011-02-27 15:49:55

+1

同意Hans的评论。我们偶尔在.NET Reflector的用户机器上得到这个报告:Application.Run()抛出一个AccessViolationException,但我们不知道为什么。这是非常罕见的,我们从来没有见过它,所以我们从来没有能够调试它。我很想知道发生了什么问题,所以我们至少可以向用户提供一些有用信息的方向,但唉,迄今为止,我被拒绝了。 – 2011-08-05 20:08:56

3

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

不知道你的用户界面上的控件和你连接的任何事件,很难确定问题到底是什么。

2

我有一个类似的问题,不像@BartRead一贯。对我而言,一些CLI代码在一个简单的Windows窗体应用程序中工作正常,但是当我将它放入larager插件生态系统(多线程)时,需要使用Application.Run或Application.DoEvents进行抽取。如果你有权访问被抽取的代码,最好的选择(对我有用)是在保持功能的同时注释越来越多的代码。事实证明,我没有GC :: Alloc'd回调/委托,虽然固定和仍然引用已在内存中移动或直接标记为收集。

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

1

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

  1. 连接字符串错误。
  2. 参数类型失配(在一个长传为DB-INT32或长为nvarchar(10),这是短)