Debugging System.AccessViolationException - DllImport hell
Tags: csharp, dotnet, iis
Published: 2020-10-07 06:22:51

---
title: Debugging System.AccessViolationException - DllImport hell
published: true
description: Learn how to debug System.AccessViolationException when calling C++ code from C#, with unhandled errors in IIS modules and from the WebBrowser control.
tags: csharp, dotnet, iis
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/j1wax7kjgr010gm7gc51.png
canonical_url: https://blog.elmah.io/debugging-system-accessviolationexception/
---

For this post in the series [Debugging common .NET exceptions](https://blog.elmah.io/tag/common-exceptions/), I'll present an exception that will be uncommon for most of you and cause recurring nightmares for the rest: `System.AccessViolationException`. The exception typically happens when unmanaged code tries to read or write from/to memory that hasn't been allocated yet.

## Handling the error

Catching the exception isn't always as easy as you would think. Let's start with an example where `System.AccessViolationException` is easily handled. The following program throws and catches the exception:

```csharp
class Program
{
    static void Main(string[] args)
    {
        try
        {
            var intPtr = new IntPtr(1);
            Marshal.WriteByte(intPtr, 1);
        }
        catch (AccessViolationException e)
        {
            Console.WriteLine(e);
        }
    }
}
```

The `WriteByte` method in this example throws a new `System.AccessViolationException`. Catching the exception requires nothing more than a normal C# batch block. The exception typically produces this rather generic error message:

> Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

In most cases (at least in my experience), the `AccessViolationException` is thrown when calling C++ code through the use of `DllImport`. I remember creating a .NET program back in the day, connecting code to a phone through an old C++ API. The code relied heavily on invoking methods in unmanaged code and handling the `AccessViolationException` was a required part of writing the program. I guess that's what you get from trying to integrate with old buggy code :D

This does re-create the exception using `DllImport`, I've written the following rather buggy C++ code:

```cplusplus
#include "pch.h"
#include "Violator.h"

void ViolateMe()
{
    int* data1 = 0;
    *data1 = 0;
}
```

Visual Studio 2019 even creates a warning when building the code:

> 6011: Dereferencing NULL pointer 'data1'.

To call this from C# I'm using the following code:

```csharp
class Program
{
    static void Main(string[] args)
    {
        try
        {
            ViolateMe();
        }
        catch (AccessViolationException e)
        {
            Console.WriteLine(e);
        }
    }

    [DllImport(@"C:\path\to\ViolatorLib.dll")]
    private static extern int ViolateMe();
}
```

When running the code, the `AccessViolationException` is in fact thrown, but our catch blog is never hit. There are multiple ways of making sure that happens. One is to add the `HandleProcessCorruptedStateExceptionsAttribute` attribute to the method like this:

```csharp
class Program
{
    [HandleProcessCorruptedStateExceptions]
    static void Main(string[] args)
    {
        // ...
    }
    
    // ...
}
```

Adding `[HandleProcessCorruptedStateExceptions]` to the `Main` method, does cause the catch blog to actually catch the exception. Another approach is to set `legacyCorruptedStateExceptionsPolicy` to true in `app/web.config`:

```xml
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  ...
  <runtime>
    <legacyCorruptedStateExceptionsPolicy enabled="true"/>
  </runtime>
  ...
</configuration>
```

Microsoft seems to advise against adding that config, but I don't really agree. The reason they are doing it is that this is in fact a critical error, which probably results in an application being shut down. But you always want to tell your users that something bad happened and log the exception to your error log.

As for .NET Core, the `HandleProcessCorruptedStateExceptionsAttribute` class is in the framework, but it doesn't seem to cause `AccessViolationException` to be caught. I'm very interested in hearing people's experience with this in .NET Core.

## Debugging the error

To be honest, the `AccessViolationException` can be a nightmare to debug. In most cases, the error is produced from within unmanaged code that you won't have access to. Let's dive into different scenarios and discuss how to threat the exception in each case.

### When you have access to the unmanaged code

Let's continue the example above. In this case I do in fact have access to failing C++ code. If you step into the `ValidateMe` method using <kbd>F11</kbd> you'll notice that Visual Studio just skips over the C++ code and goes directly to the `catch` block. This is caused by native code debugging being disabled as a default. To fix that, right-click the C# project, click *Properties* and select the *Debug* tab. Below *Debugger engines* make sure to check the *Enable native code debugging* (or simply click <kbd>CTRL</kbd>+<kbd>t</kbd>). When the project is saved and the application is launched, Visual Studio now breaks inside the C++ code:

![](https://blog.elmah.io/content/images/2019/05/write-access-violation.png)

Being able to see the exact line and variable causing this error is a great help.

### When you don't have access to the unmanaged code

Bugger. You kept reading because you don't have access to the failing code, right? In this case, there's not much else to do than to contact the maintainers of the code. To help them, you can produce a memory dump of the application. To do so, run the application through Visual Studio and wait until the exception occurs. Then click Debug | Save Dump As... and name the file. The developers of the unmanaged code can use tools like WinDbg to try and find out what is going on.

Now that I've already mentioned WinDbg, you might think "why don't you just check out what's wrong using WinDbg yourself?" Good question. That is definitely possible. WinDbg definitely saved me a time or two. Using WinDbg is pretty far from the skills required by the typical .NET developer, though. If there is a general demand for it, I'll write something up. For now, you just need to know it is possible to create process memory dumps using Visual Studio.

### When using the WebBrowser control

Both Windows Forms and WPF comes with a bundled web browser component simply called `WebBrowser`. I've both experienced the `AccessViolationException`, as well as seen a lot of people complaining about the exception in this context.

The browser components were pretty buggy back in the days. In recent years, I believe most of the problems have been caused by threading issues. Web controls in C# are typically used to produce some kind of headless snapshot of an URL. I mean, how many Windows Forms applications with embedded browser capabilities are you producing these days?

When creating the `WebBrowser` control in a thread, make sure to set the correct `ApartmentState` on the thread:

```csharp
var thread = new Thread(() =>
{
   var br = new WebBrowser();
   br.Navigate(url);
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
```

The STA state is the only valid (to my knowledge) way to run ActiveX components like `WebBrowser`. As an alternative, you can still decorate a method invoked by the thread with the `[STAThread]` attribute.

### AccessViolationException inside IIS

I haven't experienced this exception on IIS, but I've seen people asking about it. The typical solution here is to make sure you are running the newest version of .NET.

Like in the example with the web browser control, a memory dump can help debug this error if handed over to someone with knowledge about WinDbg and similar tools. In order to create a memory dump from a running IIS process, you will need to locate the `w3wp.exe` process in Task Manager of the application pool running your application. When found, right-click the process and select the *Create dump file* menu item:

![](https://blog.elmah.io/content/images/2019/05/create-dump-file.png)

That was it! Unless heavily requested, this will be the last post about debugging common .NET exceptions. Check out the list of all the posts here: [Debugging common .NET exceptions](https://blog.elmah.io/tag/common-exceptions/).

## Would your users appreciate fewer errors?

elmah.io is the easy error logging and uptime monitoring service for .NET. Take back control of your errors with support for all .NET web and logging frameworks.

➡️ [Error Monitoring for .NET Web Applications](https://elmah.io/?utm_source=devto&utm_medium=social&utm_campaign=devtoposts) ⬅️

This article first appeared on the elmah.io blog at https://blog.elmah.io/debugging-system-accessviolationexception/