The following code works fine until I upgrade to .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
}
}
}
Did I just uncover a runtime bug, or is there some issue with my usage?
It can overflow. Typically the StackOverflowException is triggered by a recursive method that creates a deep call stack. The problem is linked to the concept of the stack memory region in general. Example. This program defines a method that causes an infinite recursion at runtime. The Recursive () method calls itself at the end of each invocation.
The exception that is thrown when the execution stack exceeds the stack size. This class cannot be inherited. The following example uses a counter to ensure that the number of recursive calls to the Execute method do not exceed a maximum defined by the MAX_RECURSIVE_CALLS constant.
StackOverflowException uses the HRESULT COR_E_STACKOVERFLOW, which has the value 0x800703E9. The Localloc intermediate language (IL) instruction throws StackOverflowException. For a list of initial property values for a StackOverflowException object, see the StackOverflowException constructors.
And After nearly 80,000 invocations, the stack memory space is exhausted and the program terminates. Info Usually, the StackOverflowException is caused by an infinite or uncontrolled recursion. The final numbers printed by the program execution are displayed in the Output section.
This would appear to be a bug in the CLR - you should report it to Microsoft.
Note that the StackOverflowException
occurs as the CLR attempts to execute the Crash
, not during the execution of the Crash
method - the program in fact never enters the method. This would appear to indicate that this is some low-level failure in the CLR. (Also note that the thrown exception also has no stack trace).
This exception is incredibly specific to this situation - changing any one of a number of things fixes this, for example the following code works fine:
private static void Crash()
{
bool testCrash2 = testCrash;
try { }
finally
{
HttpRuntime.Cache.Insert("xxx", testCrash2);
}
}
I would recommend that you report this to Microsoft, but attempt to work around the issue by tweaking your code in the meantime.
I can reproduce it on an x86 machine. The following code also fails:
try
{
}
finally
{
var foo = new List<object>();
foo.Add(testCrash);
}
However, the following code succeeds:
try
{
}
finally
{
var foo = new List<bool>();
foo.Add(testCrash);
}
I thought it might have something to do with the boxing of volatile fields within the finally block, but then I tried the following (which also fails):
try
{
}
finally
{
bool[] foo = new bool[1];
foo[0] = testCrash;
}
Very interesting problem...
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