Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Debugging unit tests that fail due to a StackOverflow exception

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

  • Collecting User-Mode Dumps

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?

like image 359
Justin Avatar asked Mar 11 '13 11:03

Justin


People also ask

How do I debug stack overflow exception?

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.

What is 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. } } }

What is the cause of the StackOverflow exception?

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.

How do you debug unit test cases?

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.


1 Answers

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();
        }
    }
like image 146
Diego Avatar answered Oct 13 '22 21:10

Diego