6

If I write this:

class Program
{
    static void Main(string[] args)
    {
        throw new Exception("lol");
    }
}

and run the exe from the command line, I get two entries in my event log. One is an application error that says there was an unhandled exception, and the other contains the stack trace with the source as .NET Runtime.

If I write this:

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

    static void Recurse4Evr()
    {
        Recurse4Evr();
    }
}

I only get one entry in my event log, which says Application Error and that there was a stack overflow exception. There isn't that second entry with the stack trace, so it's basically useless.

Why isn't the stack trace also logged? If I setup DebugDiag and attach it to my process and then there is a stack overflow, DebugDiag is able to log the stack trace. Obviously the stack trace is available to the outside world in some way. If the runtime is terminating the process because it detected a stackoverflow, then it also knows what the stack is.

In large applications that have many complex interactions, it is often not possible to recreate the conditions that led to a stack overflow. In this situation, a stack trace is the only way to figure out what happened. Why did microsoft decide it wasn't important to log this information? Was there a legitimate design decision that isn't obvious?

dan
  • 9,712
  • 6
  • 49
  • 62
  • 4
    My guess would be that generating the stack trace in-process requires function calls, which can't work because the stack overflowed. The debugger gets around this by being able to walk the stack using its own data structures and (hopefully) healthy stack. – siride Sep 20 '11 at 05:25
  • This is a great question! I wonder if it has to do with the way stack overflows are detected... After .Net 2.0, it seems as though you also can't catch it, either, so it seems as though it plays by a special set of rules. – J Trana Sep 20 '11 at 05:32
  • possible duplicate of [C# catch a stack overflow exception](http://stackoverflow.com/questions/1599219/c-catch-a-stack-overflow-exception) – balexandre Sep 20 '11 at 06:31
  • 1
    The stack guard page that Windows creates for the main thread isn't big enough for the CLR to reliably run code to deal with the exception. – Hans Passant Sep 20 '11 at 06:44
  • @balexandre how is this related to the other question? i'm not trying to catch a stack overflow – dan Sep 20 '11 at 15:42
  • @HansPassant couldn't the CLR temporarily acquire some extra space to figure out the stack trace and log it? I have many GB of unused memory on my server. – dan Sep 20 '11 at 16:15
  • The CLR doesn't control the creation of the main thread. It is started by Windows. – Hans Passant Sep 20 '11 at 16:28
  • @HansPassant then couldn't the thread signal to windows that it's stackoverflowing and then windows could give it some extra space for the sole purpose of logging the stack trace before it dies? – dan Sep 20 '11 at 18:56
  • Arbitrarily growing virtual memory allocations is not generally possible. The adjacent pages might well be in use. I would assume that scenarios were well-thought through before. – Hans Passant Sep 20 '11 at 19:01

2 Answers2

1

Stack overflow is considered a non-recoverable situation and for such the runtime kills the process.

to sum up:

from Damien_The_Unbeliever

From the MSDN page on StackOverflowExceptions:

In prior versions of the .NET Framework, your application could catch a StackOverflowException object (for example, to recover from unbounded recursion). However, that practice is currently discouraged because significant additional code is required to reliably catch a stack overflow exception and continue program execution.

Starting with the .NET Framework version 2.0, a StackOverflowException object cannot be caught by a try-catch block and the corresponding process is terminated by default. Consequently, users are advised to write their code to detect and prevent a stack overflow. For example, if your application depends on recursion, use a counter or a state condition to terminate the recursive loop. Note that an application that hosts the common language runtime (CLR) can specify that the CLR unload the application domain where the stack overflow exception occurs and let the corresponding process continue. For more information, see ICLRPolicyManager Interface and Hosting the Common Language Runtime.


from JaredPar

Starting with 2.0 a StackOverflow Exception can only be caught in the following circumstances.

  1. The CLR is being run in a hosted environment where the host specifically allows for StackOverflow exceptions to be handled
  2. The stackoverflow exception is thrown by user code and not due to an actual stack overflow situation (Reference)
Community
  • 1
  • 1
balexandre
  • 73,608
  • 45
  • 233
  • 342
  • i'm not trying to catch it. i'm asking why when your program terminates, and the runtime logs that there was an error in the event log, why it doesn't include the stack trace. – dan Sep 20 '11 at 15:44
  • 1
    also, I think microsoft's "advice" is very simplistic. sure, it makes sense for recursive algorithms--of course you should write fibonacci in the iterative way. my case wasn't a recursive algorithm, there was an error in the logger in my exception event handler. the logger threw, and then the event handler was triggered again, it threw again, etc. I was only able to find what caused the overflow using DebugDiag. microsoft's advice is basically "don't write code that has bugs". – dan Sep 20 '11 at 16:09
0

This is apparently not possible. If you want a stack trace so you can find the offending code that killed your application, you need to attach a 3rd party tool like DebugDiag or AdsPlus. Good luck, there is basically no documentation for these tools.

dan
  • 9,712
  • 6
  • 49
  • 62