Reputation: 7674
I have a few spots in my code where I'm simply creating a new Bitmap object, like so:
bmpTile = new Bitmap(8, 8, PixelFormat.Format32bppArgb);
Easy, right? For some reason, I randomly get exceptions on lines like this. By random, I mean that I can't consistently reproduce the same exception on the same line after the same sequence of events. I can't even create a unit test for you guys to look at.
The most common exception I get is:
ArgumentException: Parameter is not valid.
TargetSite: {Void .ctor(Int32, Int32, System.Drawing.Imaging.PixelFormat)}
The next most common one doesn't even give me a stack trace from inside my program:
AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
StackTrace:
at System.Drawing.SafeNativeMethods.Gdip.IntGdipDisposeImage(HandleRef image)
at System.Drawing.SafeNativeMethods.Gdip.GdipDisposeImage(HandleRef image)
at System.Drawing.Image.Dispose(Boolean disposing)
at System.Drawing.Image.Finalize()
TargetSite: {Int32 IntGdipDisposeImage(System.Runtime.InteropServices.HandleRef)}
It looks like it's having trouble disposing the old Bitmap whenever I try to create a new one, but why? I am using LockBits and UnlockBits ubiquitously, but I'm always doing them in pairs: I never call LockBits without a subsequent UnlockBits.
So what could cause Dispose() to fail like this?
EDIT: I should mention that it's not happening on the second try. It happens on around the fifth or sixth try, meaning it has disposed of the first four or five Bitmaps without issue.
Upvotes: 2
Views: 1235
Reputation: 941635
Both problems have the same underlying cause. Your code after LockBits() is corrupting the unmanaged heap. It is typical to use pointers or Marshal.Copy() in such code so there's no diagnostic when you write outside the bitmap boundaries. You only get an AccessViolation when you're lucky. But more typically you won't get them until later, when the heap allocator fails trying to allocate or release blocks from the heap. Very hard to diagnose since the crash location has nothing to with the original bug.
Upvotes: 2