2011-02-27 116 views
26

我們的應用程序遇到奇怪的致命System.AccessViolationException。我們看到了這些,因爲我們配置了AppDomain.CurrentDomain.UnhandledException事件來記錄異常。找到System.AccessViolationException的原因

Exception: System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt. 
    at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg) 
    at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr 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(Form mainForm) 
    at Bootstrap.Run() in e:\build-dir\src\Bootstrap.cs:line 25 

例外本身似乎並沒有包含任何不是消息更多信息「嘗試讀取或寫入受保護的內存。這通常是指示其他內存已損壞。」

  • 我們現在可以採取哪些措施來解決問題的原因?
  • 有沒有什麼辦法可以確定導致崩潰的非法地址或指針值?
  • 我們可以找出本機庫代碼導致問題的原因嗎?
  • 是否有更多的調試/跟蹤,我們可以啓用?

UPDATE

  • 難道這由早期非線程使用的WinForms的API造成的?
+1

您是否嘗試過上附加一個調試運行此,也有足夠的符號加載給一個有用的callstack? – 2012-04-20 01:52:51

回答

5

您所遇到的與「程序遇到問題並將立即關閉」的確切等效,除非它被.NET運行時捕獲,而不是被操作系統捕獲。

看着堆棧跟蹤,它並沒有被你的代碼觸發,這讓我認爲它來自你正在使用的庫或自定義控件產生的工作者線程。

跟蹤類似這樣的唯一方法是在調試器下運行本機庫,該調試器應該在訪問衝突到達CLR層之前捕獲它。這可能很容易或很難。

如果本機代碼是您自己的項目,那麼最簡單的設置方法是將.NET項目和C++項目放在同一個解決方案中,並確保.NET項目引用C++項目。如果您發佈有關您的環境的更多詳情,我可能會提供更具體的建議。

+1

這不是一個工作線程,它在主UI線程上死掉。注意Application.Run() – 2011-02-27 15:49:55

+1

同意Hans的評論。我們偶爾在.NET Reflector的用戶機器上得到這個報告:Application.Run()拋出一個AccessViolationException,但我們不知道爲什麼。這是非常罕見的,我們從來沒有見過它,所以我們從來沒有能夠調試它。我很想知道發生了什麼問題,所以我們至少可以向用戶提供一些有用信息的方向,但唉,迄今爲止,我被拒絕了。 – 2011-08-05 20:08:56

3

堆棧跟蹤指向原始調度信使的MSG參數中的錯誤數據。您是否嘗試過從Microsoft加載符號並檢查該堆棧跟蹤的參數。

不知道你的用戶界面上的控件和你連接的任何事件,很難確定問題到底是什麼。

2

我有一個類似的問題,不像@BartRead一貫。對我而言,一些CLI代碼在一個簡單的Windows窗體應用程序中工作正常,但是當我將它放入larager插件生態系統(多線程)時,需要使用Application.Run或Application.DoEvents進行抽取。如果你有權訪問被抽取的代碼,最好的選擇(對我有用)是在保持功能的同時註釋越來越多的代碼。事實證明,我沒有GC :: Alloc'd回調/委託,雖然固定和仍然引用已在內存中移動或直接標記爲收集。

如果您使用GC Alloc,請務必自行清理!

1

我在使用ADO執行存儲過程時遇到了此問題。 此錯誤有兩個原因:

  1. 連接字符串錯誤。
  2. 參數類型失配(在一個長傳爲DB-INT32或長爲nvarchar(10),這是短)