October 13, 2011

Crash IIS event 5011 and how to add your unhandled exceptions in the event viewer

Recently I had a bug in one of my website because of a recursive infinite loop. The effect was some random restart of IIS but noting in the sitecore logs and not way to know why.

In the windows event viewer I saw in the IIS section that the I had some IIS crashes with the event code 5011.

After googling a little bit I found this website: http://martinnormark.com/how-to-handle-iis-event-id-1009-event-id-5011-on-iis-7

So, if you create a dll with this class

#region Using

using System;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Web;


/// <summary>
/// Handles all unhandled exceptions from in the current AppDomain. 
/// Works great to catch unhandled exceptions thrown by IIS's child threads, /// which will make the application pool terminate unexpectedly 

/// without logging. This makes sure your Exception /// is logged to the Application event log.
/// </summary>
public class UnhandledExceptionModule : IHttpModule
  #region Fields

  private static int _UnhandledExceptionCount = 0;
  private static string _SourceName = null;
  private static object _InitLock = new object();
  private static bool _Initialized = false;


  #region IHttpModule members

  public void Init(HttpApplication app)

    // Do this one time for each AppDomain.
    if (!_Initialized)
      lock (_InitLock)
        if (!_Initialized)
          string webenginePath = Path.Combine(RuntimeEnvironment.GetRuntimeDirectory(), "webengine.dll");

          if (!File.Exists(webenginePath))
            throw new Exception(String.Format(CultureInfo.InvariantCulture,                 "Failed to locate webengine.dll at '{0}'.  This module requires .NET Framework 2.0.", webenginePath));

          FileVersionInfo ver = FileVersionInfo.GetVersionInfo(webenginePath);
          _SourceName = string.Format(CultureInfo.InvariantCulture, "ASP.NET {0}.{1}.{2}.0", ver.FileMajorPart,                 ver.FileMinorPart, ver.FileBuildPart);

          if (!EventLog.SourceExists(_SourceName))
            throw new Exception(String.Format(CultureInfo.InvariantCulture,                 "There is no EventLog source named '{0}'. This module requires .NET Framework 2.0.", _SourceName));

          AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(OnUnhandledException);

          _Initialized = true;

  public void Dispose()


  #region UnhandledException event handler

  public void OnUnhandledException(object o, UnhandledExceptionEventArgs e)
    // Let this occur one time for each AppDomain.
    if (Interlocked.Exchange(ref _UnhandledExceptionCount, 1) != 0)

    StringBuilder message = new StringBuilder("\r\n\r\nUnhandledException logged by UnhandledExceptionModule:\r\n\r\nappId=");

    string appId = (string)AppDomain.CurrentDomain.GetData(".appId");
    if (appId != null)

    Exception currentException = null;
    for (currentException = (Exception)e.ExceptionObject; currentException != null; currentException = currentException.InnerException)

    EventLog Log = new EventLog();
    Log.Source = _SourceName;
    Log.WriteEntry(message.ToString(), EventLogEntryType.Error);


Add add this
    <add name="UnhandledExceptionModule" type="UnhandledExceptionModule"/>        

You will have more details about the cause of this error a StackOverflowException in my case.

It takes me a lot of time to find why because I didn't find how to know witch line or class cause the exception but it already help a lot :)

This class also adds all the unhandled error in the event viewer so it is also great to have it.

1 comment: