Catching Access Violation Exceptions

Catching access violation exceptions?

Nope. C++ does not throw an exception when you do something bad, that would incur a performance hit. Things like access violations or division by zero errors are more like "machine" exceptions, rather than language-level things that you can catch.

Catch c++ Access Violation exception

On Windows, you can do it with __try ... __except, as in the following simplified example:

__try
{
* (int *) 0 = 0;
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
std::cout << "Exception caught\n";
}

Microsoft call this mechanism 'structured exception handling' and it is much more powerful (and, indeed, usable) than signals on Unix and I encourage you to learn more about it if you want to do this kind of thing:

https://docs.microsoft.com/en-us/cpp/cpp/try-except-statement?view=msvc-170

I use it to catch exceptions in poorly behaved ASIO drivers which would otherwise crash my app.

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.

Catching access violations on Windows

These kind of runtime errors are handled differently, they don't produce an SEH exception. Roughly classified somewhere between "programming bug" and "malware attack". And about as informative as a uncaught C++ exception if you don't have a debugger attached, the default handler invokes instant death with __fastfail().

You'll have to call _set_invalid_parameter_handler() in your main() function to alter the way they are handled. You could throw a C++ exception in your custom handler or call RaiseException() to trigger your catch-em-all handler or just report them right there. Favor the latter, you want to ensure that the process is always terminated.

Do beware that your snippet is not the best possible example. This is UB when you build your program without iterator debugging enabled, like the Release build with default settings. UB does not guarantee you'll get an SEH exception. And if it does then you'll have to write your exception filter very carefully, it will be called with the heap lock still taken so basic stuff cannot work. Best way is to wakeup a guard process with a named event. Which then takes a minidump and terminates the program.

Catching c++ Access Violation Writing Exception?

Don't do this!

An access violation is not a C++ exception. It is the operating system trying to terminate the application because it did something invalid.

Specifically, it tried to write to a memory address it did not have the privileges to access. This basically means you're writing to random memory, which means that even if you did catch this error and showed a nice error message to the user, it might not always work. Sometimes, instead of writing to memory that you don't have write permissions for, the program might end up writing over other parts of your program. That won't raise an access violation, so the problem won't be detected. It will just corrupt your program.

The only correct way to do this is to validate your user input. You have to check that the user input is in a form that your program can handle safely. If it isn't, you have to either correct it, or abort, and show an error to the user. You have to do that in your own code, before your application does something so bad that the OS is forced to try to terminate it.

Yes, there is a way to handle Access Violations, but as I said above, that is not the correct solution to your problem, so I see no reason to elaborate on it.



Related Topics



Leave a reply



Submit