2014-12-03 71 views
8

我在c#很長一段時間,但我從來沒有得到這種錯誤。首先,你是否看到有關這個單一代碼塊的任何錯誤(可能是錯誤的)(除非它是邏輯,當然我知道它總是返回0)?AccessViolationException引發奇怪的情況

public static int GetDecimals(MySimpleEnum val) 
    { 
     int result = 0; 
     switch (val) 
     { 
      case MySimpleEnum.Base: 
      case MySimpleEnum.Slow: 
      case MySimpleEnum.Normal: 
      case MySimpleEnum.Quick: 
      case MySimpleEnum.Fastest: 
       result = 0; 
       break; 
     }    
     return result;   
    } 

發佈項目設置: DEBUG常數= FALSE; TRACE常量= true;優化代碼= true;輸出/高級/調試信息=無;

IIS = 7.5版本

此方法中,具有指定的釋放設置拋出「System.AccessViolationException:嘗試讀取或寫入受保護的存儲器這往往是一個指示其他內存已損壞。」

這裏有趣的部分。這些情況下,當它不拋出此異常:

  1. 在IIS(Express和非快速)8.5(不需要項目編輯)上運行它。
  2. 設置優化代碼= false;和Output/Advanced/Debug info = false;
  3. Wrapp裏面的方法嘗試/ catch塊(也嘗試使用log4net在catch塊中記錄異常 - 空日誌)
  4. 用一些不同的代碼替換該方法的內部。

注意事項:

  • 例外必須使用服務器上的勝利調試器被獲取(不 普通的.NET異常處理程序調用)
  • 應用程序崩潰的異常後。
  • 此代碼塊在幾個月前運行(很長一段時間沒有發佈)。錯誤開始可能會有一些更新。
  • 使用IIS 7.5和具有IIS 8.5和IIS Express(VS2012)的一臺計算機在兩臺不同的服務器上進行測試。相同的結果。我試過很多不同的項目設置組合。 Basicaly如果我沒有像第2點那樣設置設置,它會在IIS 7.5上拋出 異常。
  • 我的工作(和生成)機器運行Windows 8.1的最新更新。
  • 代碼塊位於單獨的項目(類庫)中。

我知道如何解決這個問題。但我不喜歡結束問題,但不知道原因。另外,我想在將來避免這種情況。你認爲你可以幫助我嗎?如果它是一些空引用異常,爲什麼會發生這種情況?爲什麼它是調試/發佈特定的還是IIS版本特定的?

*注2

最近,我有問題,缺少DLL的(System.Net.Http.Formatting.dll,System.Web.Http.dll,System.Web.Http.WebHost.dll),而出版。這是因爲一些Microsoft安全更新。也許這是類似的事情。*

編輯1 添加枚舉聲明的結構。

public enum MySimpleEnum 
    { 
     Base = 0, 
     Slow = 1, 
     Normal = 2, 
     Quick = 3, 
     Fastest = 4 
    } 

此外,我只是嘗試添加[MethodImpl(MethodImplOptions.NoInlining)],但沒有幫助。

+0

我不知道當方法被內聯時是否發生崩潰。嘗試標記它[[MethodImpl(MethodImplOptions.NoInlining)]'? – Blorgbeard 2014-12-03 21:20:52

+0

只是出於好奇,你可以顯示你的枚舉的簽名/結構..? – MethodMan 2014-12-03 21:21:58

+0

我想我們將需要看到函數被調用的上下文! – Phill 2015-06-01 09:31:32

回答

3

從託管代碼中獲取這些類型的訪問衝突錯誤是非典型的。它們來自內存破壞,可能表明有缺陷的硬件 - 在極少數情況下,這表明CLR本身存在缺陷。

這種類型的錯誤最可能的原因來自其他地方,例如,如果此代碼以某種方式使用本機代碼 - 要麼在不安全的上下文中調用本機代碼,要麼從本機代碼調用本機代碼。

引述MSDN AccessViolationException

在完全由可驗證託管代碼的程序,所有引用或者是有效或無效,並訪問衝突是不可能的。僅當可驗證的託管代碼與非託管代碼或不安全的託管代碼進行交互時纔會發生AccessViolationException。

在任何情況下,您通常需要查看代碼中的其他位置以查找破壞內存的錯誤代碼。不幸的是,這是一個很難解決的問題。祝你好運!

0

我不確定這是否仍然與您有關,但我設法通過在完全託管代碼部分中更改非常小且無關緊要的bool來生成此AccessViolation錯誤。 然而,最好的部分,如果我禁用代碼優化在該子項目的編譯器,一切運行良好。這似乎是編譯器在一個非常特殊的情況下引入的一個錯誤,它不需要具有邏輯意義。