15

We've got the problem that sometimes an AccessViolationException occurs and a simple group box gets drawn with white background and a red cross on top of it. We can't reproducable this bug reliably, it just occurs from time to time.

We don't do anything special, we're just showing a main window with a menu, toolbar, the group box on the main panel and some hyperlink controls inside the group box.

From the stack trace it seems to be a bug in Windows Forms or GDI+:

System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
   at System.Drawing.SafeNativeMethods.Gdip.GdipDrawLineI(HandleRef graphics, HandleRef pen, Int32 x1, Int32 y1, Int32 x2, Int32 y2)
   at System.Drawing.Graphics.DrawLine(Pen pen, Int32 x1, Int32 y1, Int32 x2, Int32 y2)
   at System.Windows.Forms.GroupBox.DrawGroupBox(PaintEventArgs e)
   at System.Windows.Forms.GroupBox.OnPaint(PaintEventArgs e)
   at System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer, Boolean disposeEventArgs)
   at System.Windows.Forms.Control.WmPaint(Message& m)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.GroupBox.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) 
Cœur
  • 37,241
  • 25
  • 195
  • 267
Steven
  • 161
  • 1
  • 4
  • I haven't seen this before, but I suppose that's to be expected. You say you can't reliably repro. The quick solution is probably to set the [`FlatStyle` property](http://msdn.microsoft.com/en-us/library/system.windows.forms.groupbox.flatstyle.aspx) of your `GroupBox` control to "System". It looks like the error is occurring when WinForms tries to draw the groupbox internally; if you let the system draw it, you'll bypass WinForms implementation & GDI+ altogether. That'll at least get you a working build to deploy while you figure out the real culprit. Maybe post some code to help us out there? – Cody Gray - on strike Apr 01 '11 at 08:01
  • First thing I should do is to fire up the Task Manager and display the count of User object and GDI objects to see if the app is leaking any of those. – Dan Byström Apr 04 '11 at 12:29
  • Are you using multiple threads in the calling code? – Beachwalker Jan 15 '13 at 17:45
  • I have experience the problem, some time ago. I seem to recall that it was operating system dependant and was triggered by a service pack which was then resolved later by a .NET service pack. – Jamie Clayton Jan 04 '14 at 15:21

2 Answers2

1

In Dot.Net objects are moved by the GC from one place to the other as part of memory optimization or Defragmentation process. This usually happens when sending a reference of a managed memory array (or image) to an un-managed piece of code.

The data is being moved to a different location and as the un-managed code is not aware of this it tries to access the "old" location of the data. This only happens in Release mode as in Debug mode memory optimization is switched off so ALWAYS debug in Release mode, meh...

Unfortunately, there is no way to turn off the GC defragmentation process. You can try and call the GC.Collect() and wait for it to finish before calling your GDI+ function but this will only improve the situation and not solve it completely.

The only way I was able to bypass this is to manually lock (pin) the data and release it after returned from the un-managed code, yes, back to C++. Images are tricky as you need to find the exact reference to the data in all the classes and sub-classes.

StayOnTarget
  • 11,743
  • 10
  • 52
  • 81
Gilad
  • 2,876
  • 5
  • 29
  • 40
0

Did you call GdiplusShutdown before everything was released? I asked a similar question here where I called GdiplusShutdown before my Bitmap was destroyed and also got access violation

Community
  • 1
  • 1
default
  • 11,485
  • 9
  • 66
  • 102