2012-05-31 121 views
14

我需要編寫一個測試來驗證我的代碼是否可以處理AccessViolationException(或任何其他WIN32損壞的狀態異常 - CSE),它會在不安全的上下文中出現,通常通過調用第三方庫。 這應該全部使用.NET 4.0上的C#完成。如何測試AccessViolationException的處理

我發現這個相關的問題How to handle AccessViolationException和這篇相關的文章http://dotnetslackers.com/articles/net/All-about-Corrupted-State-Exceptions-in-NET4.aspx,它解釋瞭如何捕捉這些CSE的背景。

所以我想在測試中挑起一個WIN32 CSE,以確保在我的應用程序中正確處理。喜歡的東西:

一些示例類測試:

public class MyExceptionHandler 
{ 
    [HandleProcessCorruptedStateExceptions] 
    public void HandleCorruptedStateException() 
    { 
     try 
     { 
      //Force genuine unsafe AccessViolationException 
      //not just a throw new AccessViolationException 
     } 
     catch(Exception e) 
     { 
      //Log/cleanup/other 
     } 
    } 

    public void DoesNotHandleCorruptedStateException() 
    { 
     try 
     { 
      //Force genuine unsafe AccessViolationException 
      //not just a throw new AccessViolationException 
     } 
     catch (Exception e) 
     { 
      //Log/cleanup/other 
     } 
    } 
} 

一個試驗:

class MyTest 
{ 
    [Test] 
    public void ShouldVerifyThatAnAccessViolationExceptionIsHandledCorrectly() 
    { 
     var handler = new MyExceptionHandler(); 

     Assert.DoesNotThrow(() => handler.HandleCorruptedStateException()); 
    } 

    [Test] 
    public void ShouldVerifyThatAnAccessViolationExceptionIsNotHandledCorrectly() 
    { 
     var handler = new MyExceptionHandler(); 

     Assert.Throws<AccessViolationException>(() => handler.DoesNotHandleCorruptedStateException()); 
    } 
} 

有誰對如何實現這一目標的建議,但無太多的工作(如書面方式一個不安全的。導致這個異常的lib)。

親切的問候

更新:符合我的最終解決方案,這要歸功於JaredPar。

public class MyExceptionHandler 
{ 
    [HandleProcessCorruptedStateExceptions] 
    public void HandleCorruptedStateException() 
    { 
     try 
     { 
      var ptr = new IntPtr(42); 
      Marshal.StructureToPtr(42, ptr, true); 
     } 
     catch(Exception e) 
     { 
      //Log/cleanup/other 
     } 
    } 

    public void DoesNotHandleCorruptedStateException() 
    { 
     try 
     { 
      var ptr = new IntPtr(42); 
      Marshal.StructureToPtr(42, ptr, true); 
     } 
     catch (Exception e) 
     { 
      //Log/cleanup/other 
     } 
    } 
} 

提示: 要驗證這一點手動使用一個簡單的控制檯應用程序,從命令行:

class Program 
{ 
    static void Main(string[] args) 
    { 
     var handler = new MyExceptionHandler(); 

     if (args.Length > 1) 
     { 
      handler.HandleCorruptedStateException(); 
     } 
     else 
     { 
      handler.DoesNotHandleCorruptedStateException(); 
     } 
    } 
} 

回答

24

請嘗試以下

var ptr = new IntPtr(42); 
Marshal.StructureToPtr(42, ptr, true); 

這並不能保證扔CLI規範的一個AccessViolationException,但它將在我知道的每個平臺上

+0

謝謝,但是這不會生成一個CSE,只有一個ArgumentNullException。它必須是一個真正的Win32 CSE,如果不在try try +中處理,會導致應用程序崩潰,並且如本文所述用[HandleProcessCorruptedStateExceptions]屬性等標記。 –

+0

我站好了。這是否工作: - D.我在測試中犯了一個錯誤(典型)。謝謝你太多:)。 –

0

int *p = 0xFF004324; int q = *p;

編輯出不安全的寫。從該地址讀取應該仍然會生成AccessViolationException,除非巧合地出現在您的地址空間內。

+0

OP要求提供不涉及不安全代碼的C#答案 – JaredPar