Why is ExecuteCodeWithGuaranteedCleanup not working?

I tried to "measure" the depth of the stack. Why doesn't the following program print anything?

class Program { private static int Depth = 0; static void A(object o) { Depth++; A(o); } static void B(object o, bool e) { Console.WriteLine(Depth); } static void Main(string[] args) { RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(A, B, null); } } 

Some answers simply indicate a quote from MSDN, for example, "Starting with the .NET Framework version 2.0, a StackOverflowException cannot be caught by a try-catch block, and the corresponding process ends by default." Believe me, sometimes (when there is enough space for the stack), this can be considered, the following prints a certain number just fine:

 class Program { private static int depth = 0; static void A(object o) { depth++; if (Environment.StackTrace.Length > 8000) throw new StackOverflowException("Catch me if you can."); A(o); } static void B(object o, bool e) { Console.WriteLine(depth); } static void Main(string[] args) { RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(A, B, null); } } 
+6
c #
source share
4 answers

If you want to catch it, upload it to another process (which will call you back via remote access) and allow the malicious code to be executed. Another process may end, and you can get a neat SOE that pushes the end of the pipe on your side - without the negative consequences of a rather inconvenient exception.

Note that a single AppDomain in the same process will not crop it.

If you want to get a stack trace from an exception, the following code will do you a lot of justice:

  class Program { static void Main(string[] args) { try { Recurse(0); } catch (Exception ex) { StackTrace st = new StackTrace(ex); // Go wild. Console.WriteLine(st.FrameCount); } Console.ReadLine(); } static void Recurse(int counter) { if (counter >= 100) throw new Exception(); Recurse(++counter); } } 
+5
source share

As for your editing, I don't think the user code throwing a StackOverflowException is the same as the CLR.

Here is a little discussion here .

Jeffrey (Richter, author of Microsoft.NET Framework Applied Programming ) applies to real stack overflows, that is, to stack overflows that occur if your code contains infinite recursion, something like:

void MyMethod () {MyMethod (); }

If you throw a StackOverflowException yourself, this will be handled like any other exception, and Jeffrey’s comment does not apply.

In addition, Jeffrey’s commentary states: "if the stack overflow occurs inside the ITSELF CLR ...". So, if the .NET VM can detect the stack overflow "cleanly", that is, without running MYSELF into the stack overflow, then you should get a StackOverflowException and your catch and, finally, the blocks should execute as normal. But in the tragic case, the ITSELF VM runs on the overflow stack, you are out of luck: the VM will not throw a StackOverflowException (but crash in some other weird way) and your catch and finally the blocks will not execute.

Moral: be careful with infinite recursion, because you do not have 100% guarantee that the virtual machine will detect and write them cleanly!

Bruno

Clarified who is “Jeffrey,” since the OP cited this book.

+6
source share

According to MSDN :

In previous versions of the .NET Framework, your application may catch a StackOverflowException object (for example, to restore unlimited recursion). However, this practice is currently discouraged because significant additional code is required to reliably capture the stack, avoid overflows and continue running the program.

Starting with the .NET Framework version 2.0, an exception to the StackOverflowException object cannot be caught by a block attempt and the corresponding process terminated by default. Because of this, users are encouraged to write their code to detect and prevent stack overflows. For example, if your application is dependent on recursion, usage by a counter, or a condition condition, complete a recursive loop. Note that the application hosting the common CLR runtime indicates that the CLR unloads the application area in which the stack throws an overflow exception and the corresponding process continues. For more information, see ICLRPolicyManager Interface and Common Language Runtime Hosting.

In this regard, I do not believe that you can do what you want, since "StackOverflowException will complete the process."

+3
source share

Starting with the .NET Framework version 2.0, a StackOverflowException cannot be caught by a try-catch block, and the corresponding process terminates by default.

0
source share

All Articles