It is really interesting that the following C# code will crash on .NET4.0 but work fine on .NET2.0.
C# code
class Program { static void Main(string[] args) { try { ExceptionTest(); Console.WriteLine("Done!"); } catch (Exception e) { Console.WriteLine("Error !!!"); Console.WriteLine(e.Message); } } [DllImport("badapp")] private static extern int ExceptionTest(); }
C++ code
extern "C" __declspec(dllexport) int ExceptionTest() { IUnknown* pUnk = NULL; pUnk->AddRef(); return 0; }
If compiling the above C# code against .NET2.0, everything works fine. Only compiling it against .NET4.0 will make it crash at runtime.
I'm suspecting that system exception catch mechanism has been changed since .NET4.0. Any ideas?
To handle such an AccessViolationException exception, apply the HandleProcessCorruptedStateExceptionsAttribute attribute to the method in which the exception is thrown. This change does not affect AccessViolationException exceptions thrown by user code, which can continue to be caught by a catch statement.
Any operation that attempts to reference a null reference in verifiable code throws a NullReferenceException exception. An AccessViolationException occurs only when verifiable managed code interacts with unmanaged code or with unsafe managed code.
Starting with .NET Framework 4, AccessViolationException exceptions thrown by the common language runtime are not handled by the catch statement in a structured exception handler if the exception occurs outside of the memory reserved by the common language runtime.
I understand that it's nearly inevitable that AccessViolationException will happen at some point if you deploy application at scale to unknown environments. However, in .NET programs the major cause of these exceptions are unmanaged libraries and improper interfaces to unmanaged libraries.
Yes, it changed in .NET 4. You cannot catch exceptions that indicate a corrupted state. This is because there's pretty much no guarantee that you can do anything at all when a corrupted state exception is thrown. There is practically no reason to want a process with corrupted state to continue executing.
For compatibility with older code, you can change this behaviour by adding the legacyCorruptedStateExceptionsPolicy
element to app.config.
You can also do it on a case-by-case basis by marking methods where you want to catch these exceptions with the HandleProcessCorruptedStateExceptions attribute.
[HandleProcessCorruptedStateExceptions] public static unsafe int LenghtPoint(this IntPtr point) { //por optimizar byte* bytePoint = (byte*)point.ToPointer(); byte auxByte; int length = 1; bool encontrado = false; while (!encontrado) { try { auxByte = bytePoint[length]; length++; } catch (System.AccessViolationException) { length--; encontrado = true; } } return length; }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With