StackOverflowException в .NET 4

Следующий код работает нормально, пока я не перейду на .NET 4 (x64)

namespace CrashME
{
    class Program
    {
        private static volatile bool testCrash = false;
        private static void Crash()
        {
            try
            {
            }
            finally
            {
                HttpRuntime.Cache.Insert("xxx", testCrash);
            }

        }

        static void Main(string[] args)
        {
            Crash();
            // Works on .NET 3.5 , crash on .NET 4
        }
    }
}

Я только что обнаружил ошибку времени выполнения, или есть некоторые проблемы с моим использованием?

Ответы

Ответ 1

Это будет ошибкой в ​​CLR - вы должны сообщить об этом Microsoft.

Обратите внимание, что StackOverflowException происходит, когда CLR пытается выполнить Crash, а не во время выполнения метода Crash - программа на самом деле никогда не входит в этот метод. Это, по-видимому, указывает на то, что это небольшой сбой низкого уровня в CLR. (Также обратите внимание, что в заброшенном исключении также нет трассировки стека).

Это исключение невероятно специфично для этой ситуации - изменение какого-либо одного из ряда вещей исправляет это, например, следующий код работает нормально:

private static void Crash()
{
    bool testCrash2 = testCrash;
    try { }
    finally
    {
        HttpRuntime.Cache.Insert("xxx", testCrash2);
    }
}

Я бы порекомендовал вам сообщить об этом Microsoft, но попытайтесь обойти эту проблему, настроив ваш код тем временем.

Ответ 2

Я могу воспроизвести его на машине x86. Не удалось выполнить следующий код:

        try
        {
        }
        finally
        {
            var foo = new List<object>();
            foo.Add(testCrash);
        }

Однако следующий код преуспевает:

        try
        {
        }
        finally
        {
            var foo = new List<bool>();
            foo.Add(testCrash);
        }

Я думал, что это может иметь какое-то отношение к боксу летучих полей в блоке finally, но затем я попробовал следующее (что тоже не удается):

        try
        {
        }
        finally
        {
            bool[] foo = new bool[1];
            foo[0] = testCrash;
        }

Очень интересная проблема...