Getting ReportAvOnComRelease Exception when using 3rd party COM
I am a new C# programmer and have created an application which uses a 3rd party COM object to track telephone call recordings from a call recording server. The creator of the COM software is also the vendor who makes the call recording software, so you would think it should work. I have been on many phone calls and code reviews with their staff and they have come up with very little to help.
The application responds to events from the COM object like OnCallStart and OnCallEnd, AgentLogon, AgentLogoff, ServerDown, etc. I do nothing more than monitor what the events return and write it to a file. The application compiles without a problem and runs for a few minutes and then it gives me the following error (I had to open up the Exception in the Debug>Exceptions menu to finally see it):
ReportAvOnComRelease was detected
Message: An exception was caught but handled while releasing a COM interface pointer through Marshal.Release or Marshal.ReleaseComObject or implicitly after the corresponding RuntimeCallableWrapper was garbage collected. This is the result of a user refcount error or other problem with a COM object's Release. Make sure refcounts are managed properly. The COM interface pointer's original vtable pointer was 0x45ecbac. While these types of exceptions are caught by the CLR, they can still lead to corruption and data loss so if possible the issue causing the exception should be addressed.
It gives me no more than that. No vtable details, refcounts or anything else. I coded a GC.Collect() and let the app开发者_如何学Go run for a minute and then fired the GC.Collect and got the error. I can do that with some consistency. I have read article after article about this error and the need to Marshal correctly, but I am not the one marshaling. VS creates a RCW for the COM object and I use that so I have no control there, or do I? None of the articles gave me any code examples or anything other than theoretical chit chat.
Is there a better way to do this? How can I find exactly what is causing the error? There seems to be no way to isolate this thing. I found one article from a guy from Microsoft that called this the "Silent Assassin", but he gave no solutions and essentially admitted that MS didn't have any either. Read Here
I am at my wits end. Any help is appreciated.
Well, it is a serious defect in the COM server you are using. Yes, it is indirectly triggered by the CLR, the last reference count of a COM object is released when the finalizer thread runs the RCW finalizer. Marshal.ReleaseComObject counts the reference count down to 0 and the COM server's IUnknown::Release() implementation method will clean up the object.
That's always a vulnerable time for a COM server. When it corrupted the heap earlier, a common time for this to trigger a CPU hardware fault (AV = Access Violation) is when it releases memory. Microsoft put a catcher for this hardware exception in place to help diagnose the problem. Without it, you'd have very little chance to figure out what happened because the finalizer runs at an unpredictable time without any of your own code actively running.
The fault is quite serious, you're left with a corrupted heap that's only partly cleaned up. If you keep going, you'll typically just get more AVs and/or you'll leak memory. The worst possible outcome, quite likely btw, is that it doesn't die afterwards but just starts generating bad data or misbehaves unpredictable, causing you to think that it is your code that is buggy.
There's only one party that can fix this problem, the supplier of this COM server. Carefully specify the machine you are running on, especially the operating system version is important, and give them a small piece of code (source included) that reproduces the exception. Keeping it small and highly visible is important or they'll claim it was your code that corrupted the heap. They are likely to do so anyway, heap corruption is very difficult to debug. If you cannot get them responsive, you'd be wise to shop for another vendor.
精彩评论