28

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?

Miles Chen
  • 793
  • 1
  • 10
  • 20

2 Answers2

50

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.

R. Martinho Fernandes
  • 228,013
  • 71
  • 433
  • 510
  • 1
    I'd been chasing this issue for a week! The one thing I can usefully do with my corrupted state is restart. Its a console app that *should* be running 24hrs a day. Now it will. – Andiih Nov 27 '13 at 15:55
  • @Andiih unless the corrupted bits are the code that would restart it. I would use external watchdogs for this purpose. – R. Martinho Fernandes Nov 27 '13 at 15:57
  • Thx. We have an external watchdog too (have had for some time), but this enables a much quicker restart where its possible to do it. – Andiih Nov 27 '13 at 16:13
4
    [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;
    }
Gabriel
  • 41
  • 1