.NET Exceptions – System.AccessViolationException

Making our way through the .NET Exception Handling series, today we’ll be exploring the System.AccessViolationException in more detail. A System.AccessViolationException occurs when unmanaged/unsafe code attempts to use memory that has not been allocated, or to memory that it doesn’t have access to.

In this article we’ll explore the System.AccessViolationException a bit more, looking at where it resides in the .NET exception hierarchy. We’ll also examine a functional C#/C++ code example to illustrate how System.AccessViolationExceptions are commonly thrown and what options you have for dealing with them in your own code, so let’s get going!

The Technical Rundown

When Should You Use It?

As mentioned in the introduction, a System.AccessViolationException can only occur when your application is using unmanaged code. For many .NET applications, this will never occur, due to how .NET handles managed versus unmanaged code.

Managed code is code that .NET compiles and executes using the common language runtime (CLR). Conversely, unmanaged code compiles into machine code, which is not executed within the safety of the CLR.

Many languages that rely on .NET, such as C# and Visual Basic, are entirely compiled and executed in the CLR. This means that code written in C# is always managed code and, therefore, can never throw a System.AccessViolationException.

However, a language like Visual C++ does allow unmanaged code to be written. In such cases, it’s entirely possible to access unallocated memory, and therefore, throw a System.AccessViolationException.

To illustrate these differences and to see how System.AccessViolationExceptions might occur in your own projects we’ll start with the full working code sample below, then break it down in more detail afterward. Since we’re using both C# and C++ in this example, we’ll start with the C# and then move onto the C++:

And here’s the (important) C++ code. While it obviously takes many more files and far more code to build a working C++ DLL, this shows the main source file (FailingApp.cpp) and the CreateReference() method we’ll be using elsewhere:

Now then, the entire purpose of the System.AccessViolationException is to inform us that something has gone wrong with our unmanaged code, so our example begins by importing a DLL using DllImport(), after which we include the method signature for the CreateReference() method that we’re importing for use in our managed C# app:

Our unmanaged C++ code is very basic and contains just the CreateReference() method, inside which we have our breaking code attempting to create an invalid reference:

With our unmanaged method imported we can try to use it in our managed C# app. We start with the ReferenceTest() method:

Here we’re making a call to the imported CreateReference() method and trying to output a succesful result, while also catching any System.AccessViolationExceptions or global Exceptions that may occur. As you might suspect, the call to our imported CreateReference() method immediately fails and throws a System.AccessViolationException. However, for applications using .NET Framework 4.0 or higher, this exception is not caught by either of our catch blocks because the exception occurs outside of the memory reserved by the common language runtime. In other words, .NET purposefully ignores exceptions that don’t occur within the managed code of our C# application — since the problem occurs within the unmanaged C++ code, we cannot catch this System.AccessViolationException by normal means. Therefore, our output just shows that an uncaught System.AccessViolationException has occurred:

However, there may be some situations where it’s beneficial to actually catch System.AccessViolationExceptions and similar unmanaged code exceptions directly within managed code. This can be accomplished by applying the HandleProcessCorruptedStateExceptions attribute to all methods within your managed code that should be allowed to catch System.AccessViolationExceptions which originate from unmanaged code. Therefore, our ReferenceTestWithHandler() method includes the HandleProcessCorruptedStateExceptions attribute, but is otherwise identical to what we saw before in ReferenceTest():

Now, when we execute ReferenceTestWithHandle() and reach the unmanaged CreateReference() method we still throw a System.AccessViolationException, but our catch (System.AccessViolationException exception) block is able to catch it this time and send it along to Logging.Log() for proper output:

To get the most out of your own applications and to fully manage any and all .NET Exceptions, check out the Airbrake .NET Bug Handler, offering real-time alerts and instantaneous insight into what went wrong with your .NET code, along with built-in support for a variety of popular development integrations including: JIRA, GitHub, Bitbucket, and much more.