如何测试 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 的处理的主要内容,如果未能解决你的问题,请参考以下文章