18

コードが AccessViolationException (またはその他の WIN32 Corrupted State Exception - CSE) を処理できることを確認するテストを作成する必要があります。これは、通常、サード パーティのライブラリを呼び出すことによって、安全でないコンテキストで発生します。これはすべて、.net 4.0 で C# を使用して行う必要があります。

この関連する質問How to handle AccessViolationExceptionとこの関連記事http://dotnetslackers.com/articles/net/All-about-Corrupted-State-Exceptions-in-NET4.aspxを見つけました。バックグラウンド。

したがって、アプリケーションで正しく処理されるように、テストで 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();
        }
    }
}
4

2 に答える 2

29

以下を試してください

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

これは CLI 仕様によってスローされることが保証されているわけではありませんが、AccessViolationException私が認識しているすべてのプラットフォームでスローされます。

于 2012-05-31T19:01:54.607 に答える
2
    private static unsafe void AccessViolation()
    {
        int* p = (int*)0xFF004324;
        int q = *p;
    }

安全でない書き込みを編集しました。そのアドレスから読み取ると、偶然にアドレススペース内にない限り、AccessViolationExceptionが生成されます。

于 2012-05-31T19:09:47.383 に答える