如何测试 AccessViolationException 的处理

Posted

技术标签:

【中文标题】如何测试 AccessViolationException 的处理【英文标题】:How to test handling of AccessViolationException 【发布时间】:2012-06-06 01:34:04 【问题描述】:

我需要编写一个测试来验证我的代码是否可以处理在不安全的上下文中发生的 AccessViolationException(或任何其他 WIN32 损坏状态异常 - CSE),通常通过调用第 3 方库。 这一切都应该在 .net 4.0 上使用 C# 完成。

我发现了这个相关的问题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());
    

有没有人建议如何在不做太多工作的情况下实现这一目标(例如,编写导致此异常的不安全库)。

亲切的问候

更新:为了匹配我的最终解决方案,感谢 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();
        
    

【问题讨论】:

【参考方案1】:
    private static unsafe void AccessViolation()
    
        int* p = (int*)0xFF004324;
        int q = *p;
    

编辑了不安全的写入。从该地址读取仍应生成 AccessViolationException,除非巧合的是在您的地址空间内。

【讨论】:

OP 要求提供不涉及不安全代码的 C# 答案【参考方案2】:

试试下面的

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

CLI 规范不保证会抛出AccessViolationException,但它会在我知道的每个平台上发生

【讨论】:

谢谢,但这不会生成 CSE,只会生成 ArgumentNullException。它必须是真正的 Win32 CSE,如果未在 try catch 中处理会导致应用程序崩溃 + 标有 [HandleProcessCorruptedStateExceptions] 属性等,如文章中所述。 我的立场是正确的。这确实有效:-D。我在测试中犯了一个错误(典型)。非常感谢你:)。

以上是关于如何测试 AccessViolationException 的处理的主要内容,如果未能解决你的问题,请参考以下文章

如何编写有效的测试计划

功耗如何测试?硬件怎么测试功耗?嵌入式如何测试功耗?

如何在测试文件中测试上下文?以及如何从测试文件中的上下文访问值?

如何简单设计接口测试用例

Android如何进行单元测试(转)

如何做好接口测试?