【发布时间】:2019-05-30 21:14:18
【问题描述】:
如何在 c# 中故意使带有AccessViolationException 的应用程序崩溃?
我有一个使用非托管 DLL 的控制台应用程序,该应用程序最终由于访问冲突异常而崩溃。因此,我需要故意抛出一个AccessViolationException 来测试它在某些情况下的行为。
除此之外,它必须特别是 AccessViolationException,因为这个异常不是由 catch 块处理的。
令人惊讶的是,这不起作用:
public static void Crash()
{
throw new AccessViolationException();
}
这都不是:
public static unsafe void Crash()
{
for (int i = 1; true; i++)
{
var ptr = (int*)i;
int value = *ptr;
}
}
【问题讨论】:
-
如果我正确理解文档 --> 默认情况下,公共语言运行时 (CLR) 不会将这些异常传递给托管代码,并且
try/catch块(和其他异常处理子句)不为他们调用。如果您绝对确定要保持对这些异常的处理,则必须将HandleProcessCorruptedStateExceptionsAttribute属性应用于要执行其异常处理子句的方法 -
第二个 sn-p 肯定是在正确的轨道上。但是使用
*(int*)0x10000 = 0;生成AVE而不是NRE,0x10000以下的地址被认为是由空指针引起的。 -
@HansPassant,你能解释一下为什么是 10000 吗?它只是远离保留内存的随机值吗?
-
很多历史,可以追溯到 Windows NT,第一个 32 位版本的 Windows。他们非常担心程序员不会正确地移植他们的 16 位程序。通过使 0x10000 以下的所有内存都无法访问,它们可以生成有用的诊断信息。当程序访问对象的字段时,空指针还可以生成对非 0 地址的内存访问。 C# 有一个很好的保证,它不会导致误导性异常,它生成的代码会在对对象进行任何操作之前检查对象的地址。
标签: c# access-violation