2008-10-08 154 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。我只希望它不會引入任何新的錯誤。

相關問題