Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

StackOverflowException in .NET

Tags:

.net

exception

After hitting a few StackOverflowExceptions in .NET I noticed they completely bypass the unhandled exception handlers that .NET offers (Application.ThreadException / AppDomain.UnhandledException). This is very disturbing since we have critical cleanup code in those exception handlers.

Is there any way to overcome this?

like image 486
adams Avatar asked Sep 20 '08 09:09

adams


People also ask

What is StackOverflowException in C#?

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

Can you catch a StackOverflowException C#?

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.

What causes stack overflow C#?

What causes stack overflow? One of the most common causes of a stack overflow is the recursive function, a type of function that repeatedly calls itself in an attempt to carry out specific logic. Each time the function calls itself, it uses up more of the stack memory.


1 Answers

There are three kind of so-called "asynchronous exceptions". That are the ThreadAbortException, the OutOfMemoryException and the mentioned StackOverflowException. Those excepions are allowed to occur at any instruction in your code.

And, there's also a way to overcome them:

The easiest is the ThreadAbortException. When the current code executes in a finally-block. ThreadAbortExceptions are kind of "moved" to the end of the finally-block. So everything in a finally-block can't be aborted by a ThreadAbortException.

To avoid an OutOfMemoryException, you have only one possibility: Do not allocate anything on the Heap. This means that you're not allowed to create any new reference-types.

To overcome the StackOverflowException, you need some help from the Framework. This help manifests in Constrained Execution Regions. The required stack is allocated before the actual code is executed and additionally also ensures that the code is already JIT-Compiled and therefor is available for execution.

There are three forms to execute code in Constrained Execution Regions (copied from the BCL Team Blog):

  • ExecuteCodeWithGuaranteedCleanup, a stack-overflow safe form of a try/finally.
  • A try/finally block preceded immediately by a call to RuntimeHelpers.PrepareConstrainedRegions. The try block is not constrained, but all catch, finally, and fault blocks for that try are.
  • As a critical finalizer - any subclass of CriticalFinalizerObject has a finalizer that is eagerly prepared before an instance of the object is allocated.
    • A special case is SafeHandle's ReleaseHandle method, a virtual method that is eagerly prepared before the subclass is allocated, and called from SafeHandle's critical finalizer.

You can find more at these blog posts:

Constrained Execution Regions and other errata [Brian Grunkemeyer] at the BCL Team Blog.

Joe Duffy's Weblog about Atomicity and asynchronous exception failures where he gives a very good overview over asynchronous exceptions and robustness in the .net Framework.

like image 97
Thomas Danecker Avatar answered Sep 28 '22 06:09

Thomas Danecker