Tutorial :Access violation when accessing a COM object from .Net



Question:

I am sorry if the post is too long, but I would be happy if someone would at least point read the bolded titles, and point me in the right direction. I am having this problem for couple of days, but was unable to found the answer on the net. These are the things I have found out so far.

1. "Access violation" exception crushes my managed application

My C# WinForms app sometimes closes with an "Access violation" exception ("Attempted to read or write protected memory"), right in the moment when selecting a TabPage in a windows form TabControl. From the stack trace (try/catch around Application.Run) I can see that the exception happens at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg), called inside UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData).

  -- Message: Attempted to read or write protected memory.     This is often an indication that other memory is corrupt.  -- Stack trace:     at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)     at System.Windows.Forms.Application.ComponentManager        .System.Windows.Forms.UnsafeNativeMethods        .IMsoComponentManager.FPushMessageLoop        (Int32 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(ApplicationContext context)     at MyApp.Program.Main()  

2. The faulting module seems to be a COM object (ChartFX Client Server 6.2)

Using WinDbg (with SoS loaded), I caught it on the unmanaged side, inside ChartFX.ClientServer.Core.dll (that's a COM charting component we are using):

  (ca84.c98c): Access violation - code c0000005 (first chance)  First chance exceptions are reported before any exception handling.  This exception may be expected and handled.  eax=00000000 ebx=06e67c38 ecx=06e67c38 edx=000018c6 esi=06e7df30 edi=317a9e80  eip=31666110 esp=0015e040 ebp=0015e08c iopl=0         nv up ei pl zr na pe nc  cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010246  ChartFX_ClientServer_Core!Ordinal5507+0x97b7:  31666110 8a404d          mov     al,byte ptr [eax+4Dh]      ds:0023:0000004d=??  

[edit:] I also wasn't able to get the unmamanged stack details from WinDbg (it said "Stack unwind info not available"):

  0:000> kP  ChildEBP RetAddr    WARNING: Stack unwind information not available. Following frames may be wrong.  0015e08c 3166288b ChartFX_ClientServer_Core!Ordinal5507+0x97b7  0015e394 3165a921 ChartFX_ClientServer_Core!Ordinal5507+0x5f32  0015e480 31678685 ChartFX_ClientServer_Core!Ordinal5496+0x26a  0015e568 3167bef4 ChartFX_ClientServer_Core!Ordinal5492+0x975  0015e668 316a356b ChartFX_ClientServer_Core!Ordinal5492+0x41e4  0015e77c 31709496 ChartFX_ClientServer_Core!Ordinal443+0x5745  0015e7d0 31707f70 ChartFX_ClientServer_Core!Ordinal2584+0x3cdc  0015e7f8 3170817d ChartFX_ClientServer_Core!Ordinal2584+0x27b6  0015e81c 3162fd76 ChartFX_ClientServer_Core!Ordinal2584+0x29c3  0015e86c 7719f8d2 ChartFX_ClientServer_Core!Ordinal899+0x6b6  0015e898 7719f794 USER32!GetMessageW+0x93  0015e910 771a06f6 USER32!GetWindowLongW+0x115  0015e940 771a069c USER32!CallWindowProcW+0x75  0015e960 747fcef4 USER32!CallWindowProcW+0x1b  0015e97c 747fd073 comctl32!Ordinal377+0x5c  0015e9e0 747fd027 comctl32!DefSubclassProc+0x92  0015ea04 747fd4e6 comctl32!DefSubclassProc+0x46  0015ea20 747fd073 comctl32!DefSubclassProc+0x505  0015ea84 747fd118 comctl32!DefSubclassProc+0x92  0015eae4 7719f8d2 comctl32!DefSubclassProc+0x137  

3. Bug is not easy to reproduce (although it can be provoked usually in less than 5 min.)

I have several Chart instances in several TabPages, and this usually happens while I am switching the tabs. I still don't know how to reproduce it, besides switching those tabs for several minutes before it happens, so I cannot use our source control to reliably find the build which didn't have this problem. I am accessing the charts through the managed AxChart wrapper class (derived from AxHost), which was created by VS designer automatically.

4. What should be my next step?

If someone could point me to the next step I should do to find the actual cause, I would be very grateful. Experimenting (removing and returning code) does not do much good, because I don't know how to reproduce it, so it would take large amounts of time on each iteration just to convince myself that the bug is still there.

I have found that people often suggest something like "switching compiler optimizations", but since the exception is not thrown deterministically, I don't want to simply rearrange some bytes and hope that it never returns.

Thanks a lot in advance!

Best regards, Groo


Solution:1

By adding lots of log traces all over the code, I've managed to notice that in some cases one of the Chart's properties turns into Double.NaN. After I get that, app always crashed during next Chart repaint. By handling the Chart's PrePaint and PostPaint events (luckily it has these events), I confirmed that the crash happens right between these two events.

In particular, it only happens if I set the chart's zoom before it has been painted for the first time (first time since the last update). I managed to do it in a different way, and it hasn't crashed since.

I am not very satisfied with this "solution", since it is obviously some internal problem which cannot be precisely detected before it actually crashes, and I may be only hiding it this way. But I have to leave it as it is for now because I am losing too much time otherwise.

[Update]

Replicated the bug successfully

I did a quick test app, where I set some chart's properties twice, before it is actually painted, and application crashes immediately. I have reported the bug to Software FX, but got no answer. This is not the first irritating bug I am having with this control, but for our next release we're switching to their managed (.Net) version, so we will at least have Reflector to find out how to resolve those bugs.

Anyway thanks everyone!


Solution:2

It looks very much like a thread safety issue.
I would suggest you start by reading the control's documentation, looking specifically for mention of thread-safety. The threading model typically used by COM components is different - and often incompatible - with (trivial) .NET usage.


Solution:3

Had one of these a while back. Our case in point was a PInvoke call: OpenPrinter(string port);

Our issue was that the managed code sent: "LPT1:" but the unmanaged code declared a byte[1024] array and read 1024 bytes onwards from the address of the string. This would read outside of the bounds of the allocated string ("LPT1:") and occasionally wander into memory that wasn't allocated for the application thereby causing this intermittent AccessViolationException.

We fixed this by changing the call to: OpenPrinter(int length, string port) so the unmanaged code could declare a byte array that was the correct length.

This post by ctacke also has some goodies on trying to work out what might be causing this issue.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »