Help me understand "StackOverflowException"

J

Jesee

I am reading Jeffrey Richter's book "Applied Microsoft .NET Framework
programming",i came across "Exception handing". Page 405 says
"If the stack overflow occurs within the CLR itself,your application code
won't be able to catch the StackOverflowException exception and none of your
finally blocks will excute.",I don't understand it.
Following C# statement:
class App
{
static void Main()
{
try
{
Console.WriteLine("This process will throw a StackOverflowException");
ThrowStack();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
Console.WriteLine("Finally block execute");
Console.ReadLine();
}
}

static void ThrowStack()
{
try
{
throw new StackOverflowException("StackOverflowException is be throw by
user");
}
catch (StackOverflowException ex)
{
throw ex;
}
}
}
output:

This process will throw a StackOverflowException
StackOverflowException is be throw by user
Finally block execute

It seems catch block catch this exception and finally black execute,why?

Thanks for your help
 
B

Bruno Jouhier [MVP]

Jeffrey's comment applies to real stack overflows, i.e. to stack overflows
that occur if your code contains an infinite recursion, something like:

void MyMethod() { MyMethod(); }

If you throw the StackOverflowException yourself, it will be handled like
any other exception, and Jeffrey's comment does not apply.

Also, Jeffrey's comment says: "if the stack overflow occurs WITHIN THE CLR
ITSELF ...". So, if the .NET VM can detect the stack overflow "cleanly",
i.e. without running ITSELF into a stack overflow, then you should get a
StackOverflowException and your catch and finally blocks should execute as
usual. But, in the tragic case where the VM ITSELF runs into a stack
overflow, you won't be as lucky: the VM will not propagate a
StackOverflowException (but crash in some other weird way) and your catch
and finally blocks won't execute.

Morale is: be careful with infinite recursion because you don't have a 100%
guarantee that the VM will detect and signal them cleanly!

Bruno.
 
G

Gheorghe Marius

Hello Bruno,

Do you onestly think that is even a 1% chance for CLR to run into a Stack
overflow ?

Cheers,
Marius.
 
J

Jesee

You said "the VM ITSELF runs into a stack
overflow ,the CLR will not propagate a StackOverflowException" £¬i.e. catch
bolck statement won't catch "StackOverflowException" and finally block
statement won't execute.
but Following C# statement:
namespace Test
{
class App
{
static void Main()
{
try
{
InfiniteLoop();
}
catch (StackOverflowException)
{
Console.WriteLine("StackOverflowException occur");
}
finally
{
Console.WriteLine("Finally block execute");
Console.ReadLine();
}
}

static void InfiniteLoop()
{
InfiniteLoop();
}
}
}

output:
StackOverflowException occur
Finally block execute

as you say,the catch block won't catch StackOverflowException and finally
block statement won't executed.but,really,the finally block statement
executed.Why?


Thanks for your help.
 
B

Bruno Jouhier [MVP]

Definitely! I ran into it today, by coincidence. The VM crashed with a
strange message about the debugger and the JIT compiler getting into each
other's way, because I had an infinite recursion (had not happened to me for
a long while but it had to be today ;-)).
So, yes, "shit happens".

Bruno.
 
B

Bruno Jouhier [MVP]

Why?

Because you were lucky! The VM noticed that the stack was going to overflow
early enough, and there was enough stack left so that VM could allocate the
StackOverflowException and throw it. And everything worked as expected.

But there are situations were you might not be as lucky (I ran into one
today, by pure coincidence but I can't reproduce it on a simple case) and
were the VM does not have enough stack left to handle the overflow cleanly.
At some point the VM needs to call new StackOverflowException to create the
exception, and this causes a call to the memory manager, which calls some
internal methods, so you need a bit a stack to do this. In these ugly cases,
the VM does not have enough stack and crashes with a weird message!

Bruno.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top