Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stack overflow in .NET sends IIS to 100% CPU usage - why no StackOverflowException?

I had some code in an ASP.NET application running on Server 2008 R2 + IIS 7.5. Whenever I loaded a particular page, it would hang forever and send IIS to 100% CPU usage. I eventually tracked down the problem.

public string Comments
{
    get { return this.Comments; }
}

Oops - should have been return this.Photo.Comments. So, my question is, why didn't .NET generate a StackOverflowException, but instead let IIS run at 100% CPU for far longer than it should have taken. In my experience programming with .NET, it takes seconds or less to get a StackOverflowException when doing something like the above. So how could it still be running for almost 30 minutes on IIS?

like image 370
Jake Petroules Avatar asked May 10 '11 08:05

Jake Petroules


2 Answers

It's possible the JIT compiler optimised out a method call to YourClass::get_Comments() (which is what the IL would look like) and inlined the code with a jmp (or whatever the x86 assembler would be) loop construct because there weren't any values being passed around. Just a thought.

This old article is worth a look:

Jit Optimizations: Inlining (II)

"A typical example of a really good candidate for inlining is a property getter/setter. These are usually really small methods that usually just do a memory fetch or store, so it's usually a size and speed win to inline them."

As is:

Writing High-Performance Managed Applications : A Primer - Managed Code and the CLR JIT

I also reproduced this with a simple console application:

class Program
{
  static void Main(string[] args)
  {
    MyClass mc = new MyClass();
    string s = mc.Comments;
  }
}

public class MyClass
{
  public string  Comments
  {
    get { return this.Comments; }
  }
}

In debug mode with optimisations turned off I get a stack overflow exception thrown. Upon turning on Jit Optimisations and compiling a release build the app just runs forever. This suggests that inlining to a loop has probably happened.

This also appears to be the case with C#2.0, 3.0 and 4.0.

like image 106
Kev Avatar answered Sep 23 '22 15:09

Kev


I tried putting this code into a class library and running it with a unit test.

It crashes the MS test agent with a stack overflow exception.

What may be happening is that you are getting a stackoverflow exception. This is crashing the application pool. IIS then pulls up a new copy of the app pool, and it gets crashed again ....

Check your event logging for application pool recycling / stops.

like image 25
Shiraz Bhaiji Avatar answered Sep 21 '22 15:09

Shiraz Bhaiji