How to Handle Accessviolationexception

How to handle AccessViolationException

EDIT (3/17/2021)

Disclaimer: This answer was written in 2011 and references the original .NET Framework 4.0 implementation, NOT the open-source implementation of .NET.


In .NET 4.0, the runtime handles certain exceptions raised as Windows Structured Error Handling (SEH) errors as indicators of Corrupted State. These Corrupted State Exceptions (CSE) are not allowed to be caught by your standard managed code. I won't get into the why's or how's here. Read this article about CSE's in the .NET 4.0 Framework:

http://msdn.microsoft.com/en-us/magazine/dd419661.aspx#id0070035

But there is hope. There are a few ways to get around this:

  1. Recompile as a .NET 3.5 assembly and run it in .NET 4.0.

  2. Add a line to your application's config file under the configuration/runtime element:
    <legacyCorruptedStateExceptionsPolicy enabled="true|false"/>

  3. Decorate the methods you want to catch these exceptions in with the HandleProcessCorruptedStateExceptions attribute. See http://msdn.microsoft.com/en-us/magazine/dd419661.aspx#id0070035 for details.


EDIT

Previously, I referenced a forum post for additional details. But since Microsoft Connect has been retired, here are the additional details in case you're interested:

From Gaurav Khanna, a developer from the Microsoft CLR Team

This behaviour is by design due to a feature of CLR 4.0 called Corrupted State Exceptions. Simply put, managed code shouldnt make an attempt to catch exceptions that indicate corrupted process state and AV is one of them.

He then goes on to reference the documentation on the HandleProcessCorruptedStateExceptionsAttribute and the above article. Suffice to say, it's definitely worth a read if you're considering catching these types of exceptions.

How to handle System.AccessViolationException?

For clarity I copy/paste the answer given in the comments by Flot2011 here:

There are a few ways to get around this:

  • Recompile as a .NET 3.5 assembly and run it in .NET 4.0.
  • Add a line to your application's config file under the configuration/runtime element: <legacyCorruptedStateExceptionsPolicy enabled="true|false"/>
  • Decorate the methods you want to catch these exceptions in with the HandleProcessCorruptedStateExceptions attribute. See this article for details.

Is it possible to catch an access violation exception in .NET?

You shouldn't. An access violation is a serious problem: it is an unexpected attempt to write to (or read from) an invalid memory address. As John already clarified, the unmanaged DLL might already have corrupted the process memory before the access violation has been raised. This can have unpredicted effects on any part of the current process.

The safest thing to do is to possibly inform the user and then immediately exit.

Some more details: An access violation is an OS exception (a so-called SEH or structured exception handling exception). This is a different kind of exception than the managed CLR exceptions from System.Exception. You will rarely see SEH exceptions in purely managed code, but if one occurs, e.g. in unmanaged code, the CLR will deliver it to managed code where you are also able to catch it1.

However, catching SEH exceptions is mostly not a good idea. Further details are explained in the article Handling Corrupted State Exceptions in MSDN magazine where the following text it taken from:

The CLR has always delivered SEH exceptions to managed code using the same mechanisms as exceptions raised by the program itself. This isn't a problem as long as code doesn't attempt to handle exceptional conditions that it cannot reasonably handle. Most programs cannot safely continue execution after an access violation. Unfortunately, the CLR's exception handling model has always encouraged users to catch these serious errors by allowing programs to catch any exception at the top of the System.Exception hierarchy. But this is rarely the right thing to do.

1This was true until .NET 3.5. In .NET 4 the behavior has been changed. If you still want to be able to catch such kind of exceptions you would have to add legacyCorruptedState­­ExceptionsPolicy=true to the app.config. Further details in the articled linked above.

C# Occasional AccessViolationException

An AccessViolationException is an exception typically raised when your process tries to access memory that's not its own. (Incidentally, a NullReferenceException is just an AccessViolationException at low addresses, served with a different name, to give you a hint as to what caused it.) Thus, it's reasonable to say that this is more or less what happens inside your program: a dereference of an invalid pointer (possibly a null pointer) or access beyond the boundaries of a particular buffer.

If you're not messing with pointers, your code is not responsible for the problem. The constructor you are invoking is responsible for doing something unsafe and invalid. If the library you're using is open source, you can go in and try to diagnose the problem yourself, by looking for suspicious behaviors like those described above. You can then go ahead and try to fix it (and possibly contribute your fix to the developers of that library).

If the above can't be done for any reason, there is a workaround. By default, managed code cannot catch an AccessViolationException, because it's a Corrupted State Exception (CSE), but you can opt-in to handling such exceptions either globally (by applying a fix described in another answer) or per method (by using the [HandleProcessCorruptedStateExceptions] attribute).

However, you'll have to understand the risks taken: your program will be attempting to recover from corrupted state. If you can, try not to use a library that forces you to do that at all.

How to test handling of AccessViolationException

Try the following

var ptr = new IntPtr(42);
Marshal.StructureToPtr(42, ptr, true);

This isn't guaranteed to throw an AccessViolationException by the CLI spec but it will on every platform I'm aware of

how to handle System.AccessViolationException occurred in System.Windows.Forms.dll?

Even if you set HandleProcessCorruptedStateExceptions attribute, still you need to wrap your code in try catch

[HandleProcessCorruptedStateExceptions] 
public void TheFunction()
{
try
{
// Catch any exceptions in your code
}
catch (Exception e)
{
System.Console.WriteLine(e.Message);
}
}


Related Topics



Leave a reply



Submit