当.NET应用程序因System.AccessViolation异常而崩溃时,它意味着什么?

时间:2012-10-12 14:07:40

标签: c# .net forms exception

应用程序本身长度为2000行,因此在此处粘贴代码是没有意义的,特别是因为其中一个用户收到的异常没有给出关于我的代码的哪个部分导致问题的任何提示。

顺便说一句,该应用程序只是一个带有datagridview的Windows窗体,通常只显示几百行数据和一些其他控件。在它崩溃之前,它正在非常缓慢地加载datagridview的每一行的单元格。 (但没有其他用户遇到过同样的问题。)

例外文字如下。有人可以查看它并告诉我它是由我的代码出错的东西引起的,还是可能与遇到此异常的用户的特定设置不兼容的东西?

我注意到下面的描述说内存已损坏。这是否意味着用户的计算机有坏RAM ???

  ************** Exception Text **************
  System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
     at System.Drawing.SafeNativeMethods.Gdip.GdipDrawRectangleI(HandleRef graphics, HandleRef pen, Int32 x, Int32 y, Int32 width, Int32 height)
     at System.Drawing.Graphics.DrawRectangle(Pen pen, Int32 x, Int32 y, Int32 width, Int32 height)
     at System.Windows.Forms.ControlPaint.DrawFlatCheckBox(Graphics graphics, Rectangle rectangle, Color foreground, Brush background, ButtonState state)
     at System.Windows.Forms.ControlPaint.DrawFlatCheckBox(Graphics graphics, Rectangle rectangle, ButtonState state)
     at System.Windows.Forms.ControlPaint.DrawCheckBox(Graphics graphics, Int32 x, Int32 y, Int32 width, Int32 height, ButtonState state)
     at System.Windows.Forms.ControlPaint.DrawCheckBox(Graphics graphics, Rectangle rectangle, ButtonState state)
     at System.Windows.Forms.CheckedListBox.OnDrawItem(DrawItemEventArgs e)
     at System.Windows.Forms.ListBox.WmReflectDrawItem(Message& m)
     at System.Windows.Forms.ListBox.WndProc(Message& m)
     at System.Windows.Forms.CheckedListBox.WndProc(Message& m)
     at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
     at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
     at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

2 个答案:

答案 0 :(得分:5)

没有更多代码,很难准确说出来。以下是一些需要注意的事项。

.NET是一个托管环境,其创建原则之一是能够在编译时验证代码。具体而言,这意味着可以对一个代码单元进行某些保证,例如:

  • 无法超越数组范围阅读
  • 无法修改函数指针
  • 无法读取/修改内存的代码段
  • 无法混淆对象引用的类型

尝试执行这些操作要么在编译时失败,要么在运行时出现异常。

您看到的例外是“不安全”代码的结果。不安全实际上有点用词不当 - 它更好地描述为“无法验证”。有时,出于性能原因,有必要放弃代码的可验证性,以通过指针算法之类的东西来换取原始速度。

  

此应用没有不安全的代码。

WinForms广泛使用“不安全”代码。更确切地说,你的程序集没有任何不安全的代码,但这取决于不安全的库代码。

  

我注意到下面的描述说内存已损坏。这是否意味着用户的计算机内存不良?

糟糕的RAM是可能的,但不太可能。当预期的值实际存在时,内存已损坏。这可能是由于硬件故障,也是由于软件错误。此异常通常是根据我的经验中的软件错误引起的。此消息还说内存可能已损坏。

这里的堆栈跟踪实际上可能不是很有见地,因为内存很可能在某些早期被破坏,并且只在您在此处看到的堆栈帧中检测到。

  

有一个平台调用对user32.dll的ShowWindow函数的调用(ShowWindow(p.MainWindowHandle,SW_SHOWDEFAULT);),但是这个调用发生在消息循环开始之前。

这可能是罪魁祸首。您是否尝试过使用托管Window.Show方法?可能是您的窗口还没有处理,或者它已经改变,或者由于这个原因导致任何数量的错误。一般情况下,在本机内容上使用托管包装时,请尽量避免使用PInvoke。

不幸的是,如果没有看到更多的代码,就不可能提供更有用的答案,但希望上面提供了一些异常的上下文,可以帮助你找出你的应用程序正在做什么来使WinForms进入这种状态。

答案 1 :(得分:0)

我想提一下这个,因为这个异常突然出现在我身上,花了几天时间来弄明白。我不知道上面的问题是否相关,但也许它会帮助那些搜索所述异常的人。

我正在测试一些日志记录代码,一旦签入了测试,我们就会看到构建服务器上弹出异常。我们无法在我们的开发机器上本地重新创建它。

我决定将逻辑从构造函数移动到方法,突然异常更改为System.EntryPointNotFoundException!

在我们的测试工具中,我们使用System.WebAPI安排对象,而log.WebAPI没有被记录器引用。引用正确的库可以解决问题。

<强> TL; DR;当您看到此异常时,请不要将您的业务逻辑放在Ctor中并检查您的引用。