2008-10-08 57 views
5

我有一个应用程序,只有在程序关闭后才会抛出异常。这是非常不一致的。 (我们都知道多么有趣的不一致的错误是...)程序终止后引发的异常(遇到的错误)

我的猜测是在清理过程中出现错误。但是,这些内存读/写错误似乎表明我的“不安全”代码使用情况(指针?)有问题。

我感兴趣的是调试这些情况的最佳方法是什么?
如何调试已关闭的程序?
我正在寻找一个解决更大问题的出发点。

这些错误似乎展示自己在几个方面(一些运行时,一些调试):

 
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".

回答

4

如果你的应用程序是多线程的,你可能会从工作线程中得到错误,这些工作线程没有正确终止并试图访问处置的对象。

+0

是的,它是多线程的。我意识到开发人员倾向于避免大量的线程数量的应用程序,但我的应用程序可以同时运行多个动画图形,因此显着的线程数量。 – PersistenceOfVision 2008-10-08 14:12:09

+0

多线程本身并不是一个罪过,但它更有可能不是一个错误的线程(或两个)在您的进程终止后很长一段时间内充电到远处。关闭应用程序后检查运行的进程。 – 2008-10-08 14:20:18

1

我见过plently错误的,就像这家最近。我的问题取决于CRT(C运行时间)如何与.NET运行时间互动来清理关闭进程。我的应用程序很复杂,因为它是C++,但允许COM加载项加载,其中一些是用C#编写的。

为了调试这个,我认为你将需要使用本机调试。 Visual Studio(设置为混合模式调试)或WinDbg。查找如何使用Microsoft公共符号服务器为Windows组件下载PDB - 您需要需要这些符号。

我们的许多问题都与.NET(可怕的)COM客户端支持。我说很糟糕,因为它没有正确引用计数(没有在开发者方面做很多工作)。在垃圾收集完成之前,COM对象没有被引用 - 倒计数到零。这经常在关闭期间设置奇怪的时间问题 - COM对象应该在很长的时间后清理。

1

“不一致”的发烧友词是“非确定性”。在.NET环境中会发生什么不确定性?对象破坏。

当这发生在我身上时,罪魁祸首是我编写的将不安全调用包装到外部API的类中。我将清理代码放在类的析构函数中,期望在对象超出范围时调用代码。但是,这并不是.NET中的对象破坏如何工作的,当一个对象超出范围时,它会被放入终结器的队列中,并且直到终结器接近它才会调用它的析构函数。它可能不会在程序结束之前这样做。如果发生这种情况,结果将看起来很像你在这里描述的内容。

当我完成课程后,我的课程实现了我的课程IDisposable,并明确地调用了对象Dispose(),问题就消失了。 (实现IDisposable的另一个好处是你可以在using块的开头实例化你的对象,并确信当代码离开块时Dispose()将会得到。)

0

试试这个给力的错误发生,同时程序控制

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

下的错误而停止使用建议的代码之后出现:

GC.Collect(); 
GC.WaitForPendingFinalizers(); 
6

我不得不使用AcrobarReader COM组件这个问题。应用程序退出后,我不时出现“Application.vshost.exe - 应用程序错误”,“无法读取内存”。 GC.Collect()和WaitForPendingFinalizers()没有帮助。

我的google-fu带我到这个页面:http://support.microsoft.com/kb/826220。我为我的情况修改了方法3。

使用进程资源管理器我发现AcroPDF.dll没有在Main函数的最后一行之前发布。所以,这里来了API调用。

DLLImports(dllimport的是在System.Runtime.InteropServices命名空间):

<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 

然后之前应用程序退出:

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

此过程可以被修改为任何其他病态行为DLL。我只希望它不会引入任何新的错误。

相关问题