Question

I have an application that seems to throw exceptions only after the program has been closed. And it is very inconsistent. (We all know how fun inconsistent bugs are...)

My guess is there is an error during the clean up process. But these memory read/write errors seem to indicate something wrong in my "unsafe" code usage (pointers?).

What I am interested in is what is the best method to debug these situations?
How do you debug a program that has already closed?
I am looking for a starting point to break down a larger problem.

These errors seem to present themselves in several ways (some run time, some debug):

1: .NET-BroadcastEventWindow.2.0.0.0.378734a.0:  Application.exe - Application Error
The instruction at "0x03b4eddb" referenced memory at "0x00000004". The memory could not be "written". 2: Application.vshost.exe - Application Error
The instruction at "0x0450eddb" referenced memory at "0x00000004". The memory could not be "written". 3: Application.vshost.exe - Application Error
The instruction at "0x7c911669" referenced memory at "0x00000000". The memory could not be "read". 4: Application.vshost.exe - Application Error
The instruction at "0x7c910ed4" referenced memory at "0xfffffff8". The memory could not be "read".
Was it helpful?

Solution

If your app is multi-threaded you could be getting errors from worker threads which aren't properly terminating and trying to access disposed objects.

OTHER TIPS

I had this problem using AcrobarReader COM component. Every now and then after application exit I had "Application.vshost.exe - Application Error" "memory could not be read". GC.Collect() and WaitForPendingFinalizers() didn't help.

My google-fu lead me to this page: http://support.microsoft.com/kb/826220. I modified method 3 for my case.

Using process explorer I found that AcroPDF.dll is not released before the last line in the Main function. So, here come the API calls.

DLLImports (DLLImport is in System.Runtime.InteropServices namespace):

<DllImport("kernel32.dll", EntryPoint:="GetModuleHandle", _
       SetLastError:=True, CharSet:=CharSet.Auto, _
       CallingConvention:=CallingConvention.StdCall)> _
Public Overloads Shared Function GetModuleHandle(ByVal sLibName As String) As IntPtr
End Function

<DllImport("kernel32.dll", EntryPoint:="FreeLibrary", _
    SetLastError:=True, CallingConvention:=CallingConvention.StdCall)> _
Public Overloads Shared Function FreeLibrary(ByVal hMod As IntPtr) As Integer
End Function

And then before application exit:

Dim hOwcHandle As IntPtr = GetModuleHandle("AcroPDF.dll")
If Not hOwcHandle.Equals(IntPtr.Zero) Then
    FreeLibrary(hOwcHandle)
    Debug.WriteLine("AcroPDF.dll freed")
End If

This procedure can be modified for any other ill-behaved dll. I just hope it doesn't introduce any new bugs.

I've seen plently of errors just like this recently. My issues were releated to how the CRT (C Runtime) intereacting with the .NET runtime cleans up a closing process. My application is complicated by the fact it is C++, but allows COM add-ins to to loaded, some which are written in C#.

To debug this, I think you're going to need to use native debugging. Visual Studio (set to mixed mode debugging) or WinDbg. Look up how to use the Microsoft public symbol server to download PDBs for windows components - you'll need those symbols.

Many of our problems were with .NET's (awful) COM client support. I say awful since it doesn't reference count correctly (without a lot of work on the developer's end). COM objects were not being referenced-counted down to zero until garbage collect was done. This often setup odd timing issues during shutdown - COM objects being cleaned up long after they should have been.

A fancier word for "inconsistent" is "non-deterministic." And what happens non-deterministically in the .NET environment? Object destruction.

When this happened to me, the culprit was in the class that I wrote to wrap unsafe calls to an external API. I put cleanup code in the class's destructor, expecting the code to be called when the object went out of scope. But that's not how object destruction works in .NET, When an object goes out of scope, it gets put in the finalizer's queue, and its destructor doesn't get called until the finalizer gets around to it. It may not do this until after the program terminates. If this happens, the result will look a lot like what you're describing here.

Once I made my class implement IDisposable, and explicitly called Dispose() on the object when I was done with it, the problem went away. (Another advantage of implementing IDisposable is that you can instantiate your object at the start of a using block and be confident that Dispose() will get when the code leaves the block.)

try this to force the bug to happen while under program control

   //set as many statics as you can to null;
   GC.Collect();
   GC.WaitForPendingFinalizers();
} //exit main

The error stopped appearing after using the suggested code:

GC.Collect(); 
GC.WaitForPendingFinalizers(); 
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top