mariocatch mariocatch - 9 days ago 5
C# Question

How to find the source of a StackOverflowException in my application

I have a StackOverFlow occurring somewhere in my application - and I'm trying to figure out ways to track it down.

My event logs show a crash every day or so with the following information:


Faulting application name: MyApp.exe, version: 1.0.0.0, time stamp: 0x522e8317

Faulting module name: clr.dll, version: 4.0.30319.18047, time stamp: 0x515530ce

Exception code: 0xc00000fd

Fault offset: 0x000000000000c657

Faulting process id: 0x117fc

Faulting application start time: 0x01ceadf607b184d2

Faulting application path: C:\Users\Administrator\Desktop\MyApp.exe

Faulting module path: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll

Report Id: d52424aa-1a16-11e3-bc4b-002590a4ec55


I read that 0xc00000fd is a stack overflow, but I am unsure on where it could be occurring (very large codebase), and how to track it down. Any ideas?

Answer

This is typically something I use WinDbg to track down, otherwise it's just a guessing game. Here's a quick walkthrough that should set you in the right direction.

WinDbg is a debugger for Windows, good for debugging managed and unmanaged code. It's also great for examining crash dumps. Let's start with an example program.

class Program
{
    static void Main(string[] args)
    {
        IWillStackOverflow(0);
    }

    [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
    static int IWillStackOverflow(int i)
    {
        return IWillStackOverflow(i + 1);
    }
}

This is a pretty contrived example, but let's roll with it. It does indeed stack overflow, and nor does it provide a stacktrace. This is where WinDbg comes in. First you need to install it, which is part of the Debugging Tools in the Windows SDK. There are two versions, the x64 and x86. You'll want to run the one that matches the bitness of your application.

In WinDbg, use File -> Open Executable and run your executable with WinDbg attached. The debugger will break as soon as your application loads, you can use the g command to Go and use your application until you get a StackOverflowException. Before you do that though, make sure your symbols are correct - usually running .symfix+ will correct it, then you can go.

When you get your StackOverflowException, the debugger will break on the thread that raised the exception, and the message will be something like this:

(cc0.b00): Stack overflow - code c00000fd (first chance)

Now we can load the managed debugging extensions with this command (I am assuming you are using the .NET Framework 4.0 or 4.5 here):

.loadby sos clr

And calling !clrstack. In this example, the output is:

000000d440c76040 00007ffb282b0111 StackOverflower.Program.IWillStackOverflow(Int32) [Program.cs @ 20]
000000d440c76080 00007ffb282b0111 StackOverflower.Program.IWillStackOverflow(Int32) [Program.cs @ 20]
000000d440c760c0 00007ffb282b0111 StackOverflower.Program.IWillStackOverflow(Int32) [Program.cs @ 20]
..Repeat thousands of times..

So we have our managed stack at the time of the StackOverflowException.

If your Application doesn't StackOverflow very easily, you can configure ADPlus to take a memory dump of your application at the time of the StackOverflowException. ADPlus is another big-hammer tool, but it's effective. First you need a configuration for ADPlus, here is an example one:

<ADPlus> 
   <!-- Add log entry, log faulting thread stack and dump full on first chance StackOverflow --> 
<Exceptions> 
     <Config> 
        <!-- Use sov for stack overflow exception --> 
       <Code> sov </Code> 
       <Actions1> Log;Stack;FullDump </Actions1> 
       <!-- Depending on what you intend - either stop the debugger (Q or QQ) or continue unhandled (GN) --> 
       <ReturnAction1> GN </ReturnAction1> 
     < Config> 
  </Exceptions> 
</ADPlus>

This configuration example was originally published by user jaskis on the MSDN Forums: http://blogs.msdn.com/b/jaskis/archive/2010/08/11/cwa-ends-up-with-blank-screen-on-browser-on-iis-7.aspx Then use the command line to start your application with the configuration.


This is just an example, WinDbg is a very powerful tool, though it has a bit of a learning curve. There are a lot of good resources on the internet for getting the hang of it. Tess Ferrandez has many articles in her blog that cover WinDbg and the managed debugging extensions.