How to make C# application crash with an AccessViolationException
Asked Answered
S

2

5

How to intentionally crash an application with an AccessViolationException in c#?

I have a console application that use an unmanaged DLL that eventually crashes because of access violation exceptions. Because of that, I need to intentionally throw an AccessViolationException to test how it behaves under certain circumstances.

Besides that, it must be specifically an AccessViolationException because this exception is not handled by the catch blocks.

Surprisingly, this does not work:

public static void Crash()
{
    throw new AccessViolationException();
}

Neither this:

public static unsafe void Crash()
{
    for (int i = 1; true; i++)
    {
        var ptr = (int*)i;
        int value = *ptr;
    }
}
Strader answered 30/5, 2019 at 21:14 Comment(6)
Did you read this part of the documentation?Angelitaangell
If I understand correctly the documentation --> By default, the common language runtime (CLR) does not deliver these exceptions to managed code, and the try/catch blocks (and other exception-handling clauses) are not invoked for them. If you are absolutely sure that you want to maintain your handling of these exceptions, you must apply the HandleProcessCorruptedStateExceptionsAttribute attribute to the method whose exception-handling clauses you want to executeAlmazan
Second snippet is certainly on the right track. But use *(int*)0x10000 = 0; to generate an AVE instead of a NRE, addresses below 0x10000 are assumed to be caused by null pointers.Parahydrogen
@HansPassant, could you explain why 10000? Is it just a random value far away from the reserved memory?Strader
Lot of history, goes back to Windows NT, the first 32-bit version of Windows. They were pretty worried that programmers would not port their 16-bit programs correctly. By making all of the memory below 0x10000 inaccessible they could generate a useful diagnostic. A null pointer can also generate memory accesses to addresses that are not 0, happens when a program accesses a field of an object. C# has a pretty nice guarantee that this can't cause a misleading exception, it generates code that checks the address of the object before doing anything with it.Parahydrogen
Long story short, a NRE is in fact an AVE under the hood, no distinction whatsoever to the processor. The CLR just translate it to the more understandable exception type by looking at the address. After which there is a distinction in practice, AVE is a "critical state exception" that makes the runtime decide there is something drastically wrong, NRE is a normal every day mishap.Parahydrogen
B
2

This is the "native" way - although the @Storm approach is 100% deterministic. Trick is to attempt to write into memory far away from the current pointer. I.E. even though I allocated 4 bytes in my program, the next few thousand bytes are still within the part of memory reserved for my program. Shoot far away and you should get it.

int[] array = new int[1];
fixed (int* ptr = array)
{
      ptr[2000000] = 42;
}
Brotherhood answered 30/5, 2019 at 21:33 Comment(0)
C
6

A Deterministic approach is to have Windows throw it for you:

From Петър Петров's answer to: How to make C# application crash

[DllImport("kernel32.dll")]
static extern void RaiseException(uint dwExceptionCode, uint dwExceptionFlags,  uint nNumberOfArguments, IntPtr lpArguments);

void start()
{
    RaiseException(0xC0000005, 0, 0, new IntPtr(1));
}
Cab answered 30/5, 2019 at 21:37 Comment(0)
B
2

This is the "native" way - although the @Storm approach is 100% deterministic. Trick is to attempt to write into memory far away from the current pointer. I.E. even though I allocated 4 bytes in my program, the next few thousand bytes are still within the part of memory reserved for my program. Shoot far away and you should get it.

int[] array = new int[1];
fixed (int* ptr = array)
{
      ptr[2000000] = 42;
}
Brotherhood answered 30/5, 2019 at 21:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.