Whenever a unit test fails due to a StackOverflowException
the unit test process immediately exits - the only way to find out what happened (that I am aware of) is to debug a crash dump of the unit test process obtained by following the steps found here
What is the easiest way of getting the name of the unit test that was running at the time that the StackOverflowException
was thrown? Even when debugging the unit test I'm struggling to find the name of the current unit test as its at the bottom of the stack and Visual Studio wont' shown the entire stack in the debugging window because its too large.
Is there some way to find out which unit test failed without collecting and debugging crash dumps?
Debug Diagnostics Tool (DEBUGDIAG) x you will likely be selecting IIS, select the first option. Otherwise, you likely are going to select a process or a NT Service (Windows Service). On the follow window, click the Exceptions button. From here we can specify to capture a StackOverflow exception.
A StackOverflowException is thrown when the execution stack overflows because it contains too many nested method calls. For example, suppose you have an app as follows: C# Copy. using System; namespace temp { class Program { static void Main(string[] args) { Main(args); // Oops, this recursion won't stop. } } }
StackOverflowException is thrown for execution stack overflow errors, typically in case of a very deep or unbounded recursion. So make sure your code doesn't have an infinite loop or infinite recursion. StackOverflowException uses the HRESULT COR_E_STACKOVERFLOW, which has the value 0x800703E9.
To start debugging: In the Visual Studio editor, set a breakpoint in one or more test methods that you want to debug. Because test methods can run in any order, set breakpoints in all the test methods that you want to debug. In Test Explorer, select the test method(s) and then choose Debug on the right-click menu.
As mentioned in this other question, you can't really catch a stack overflow exception unless you throw it yourself.
So, as a workaround to your problem (not really a solution) you can insert a method call in you code to detect a stack overflow, then throw the exception manually and catch it later.
[TestClass]
public class TestStackOverflowDetection
{
[TestMethod]
public void TestDetectStackOverflow()
{
try
{
InfiniteRecursion();
}
catch (StackOverflowException e)
{
Debug.WriteLine(e);
}
}
private static int InfiniteRecursion(int i = 0)
{
// Insert the following call in all methods that
// we suspect could be part of an infinite recursion
CheckForStackOverflow();
// Force an infinite recursion
var j = InfiniteRecursion(i) + 1;
return j;
}
private static void CheckForStackOverflow()
{
var stack = new System.Diagnostics.StackTrace(true);
if (stack.FrameCount > 1000) // Set stack limit to 1,000 calls
{
// Output last 10 frames in the stack
foreach (var f in stack.GetFrames().Reverse().Take(30).Reverse())
Debug.Write("\tat " + f);
// Throw a stack overflow exception
throw new StackOverflowException();
}
}
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