C# catch a stack overflow exception

2018-12-31 09:54发布

I got a recursive call to a methode that throw a stack overflow exception. The first call is surrounded by a try catch block but the exception is not caught.

Do the stack overflow exception behave in a special way ? Can I catch/handle properly the exception ?

NB : if relevant :

  • the exception is not thrown in the main thread

  • the object where the code is throwing the exception is manually loaded by Assembly.LoadFrom(...).CreateInstance(...)

9条回答
永恒的永恒
2楼-- · 2018-12-31 10:08

Yes from CLR 2.0 stack overflow is considered a non-recoverable situation. So the runtime still shut down the process.

For details please see the documentation http://msdn.microsoft.com/en-us/library/system.stackoverflowexception.aspx

查看更多
情到深处是孤独
3楼-- · 2018-12-31 10:12

It's impossible, and for a good reason (for one, think about all those catch(Exception){} around).

If you want to continue execution after stack overflow, run dangerous code in a different AppDomain. CLR policies can be set to terminate current AppDomain on overflow without affecting original domain.

查看更多
怪性笑人.
4楼-- · 2018-12-31 10:14

As several users have already said, you can't catch the exception. However, if you're struggling to find out where it's happening, you may want to configure visual studio to break when it's thrown.

To do that, you need to open Exception Settings from the 'Debug' menu. In older versions of Visual Studio, this is at 'Debug' - 'Exceptions'; in newer versions, it's at 'Debug' - 'Windows' - 'Exception Settings'.

Once you have the settings open, expand 'Common Language Runtime Exceptions', expand 'System', scroll down and check 'System.StackOverflowException'. Then you can look at the call stack and look for the repeating pattern of calls. That should give you an idea of where to look to fix the code that's causing the stack overflow.

查看更多
素衣白纱
5楼-- · 2018-12-31 10:17

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)

*"hosted environment" as in "my code hosts CLR and I configure CLR's options" and not "my code runs on shared hosting"

查看更多
查无此人
6楼-- · 2018-12-31 10:18

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.

查看更多
牵手、夕阳
7楼-- · 2018-12-31 10:19

As mentioned above several times, it's not possible to catch a StackOverflowException that was raised by the System due to corrupted process-state. But there's a way to notice the exception as an event:

http://msdn.microsoft.com/en-us/library/system.appdomain.unhandledexception.aspx

Starting with the .NET Framework version 4, this event is not raised for exceptions that corrupt the state of the process, such as stack overflows or access violations, unless the event handler is security-critical and has the HandleProcessCorruptedStateExceptionsAttribute attribute.

Nevertheless your application will terminate after exiting the event-function (a VERY dirty workaround, was to restart the app within this event haha, havn't done so and never will do). But it's good enough for logging!

In the .NET Framework versions 1.0 and 1.1, an unhandled exception that occurs in a thread other than the main application thread is caught by the runtime and therefore does not cause the application to terminate. Thus, it is possible for the UnhandledException event to be raised without the application terminating. Starting with the .NET Framework version 2.0, this backstop for unhandled exceptions in child threads was removed, because the cumulative effect of such silent failures included performance degradation, corrupted data, and lockups, all of which were difficult to debug. For more information, including a list of cases in which the runtime does not terminate, see Exceptions in Managed Threads.

查看更多
登录 后发表回答