Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does the ASP.NET "Yellow Screen of Death" display code?

I thought .Net code gets compiled into MSIL, so I always wondered how do Yellow Screens produce the faulty code. If it's executing the compiled code, how is the compiler able to produce code from the source files in the error message?

Feel free to edit this question/title, I know it doesn't really make sense.

like image 600
Kevin Avatar asked Aug 21 '08 15:08

Kevin


People also ask

What is yellow screen of death in MVC?

ASP.NET MVC application displays the flowing screen (Yellow Screen of Death) by default when an exception occurs that shows the error information if you are running it from the localhost. When you create an MVC application in Visual Studio, it does not implement any exception handling technique out of the box.

What is the yellow screen of death (ysod)?

By default, ASP.NET displays an error page that is affectionately referred to as the Yellow Screen of Death (YSOD).

Why are my Custom errors displayed as yellow?

The answer depends on how the website's <customErrors> configuration. By default, users are shown an unsightly yellow screen proclaiming that a runtime error has occurred. This tutorial shows how to customize these settings to display an aesthetically-pleasing custom error page that matches your site's look and feel.

Which error page is displayed when a user visits the application?

Which error page is displayed depends on the application's <customErrors> configuration and whether the user is visiting locally or remotely. The default behavior is to show the Exception Details YSOD to local visitors and the Runtime Error YSOD to remote visitors.


2 Answers

A .Net assembly is compiled with metadata about the bytecode included that allows easy decompilation of the code - that's how tools like .Net Reflector work. The PDB files are debug symbols only - the difference in the Yellow Screen Of Death is that you'll get line numbers in the stack trace.

In other words, you'd get the code, even if the PDB files were missing.

like image 78
Greg Hurlman Avatar answered Oct 24 '22 04:10

Greg Hurlman


like this. i've made a few changes, but it's pretty close to exactly what ms is doing.

// reverse the stack
private static Stack<Exception> GenerateExceptionStack(Exception exception)
{
    var exceptionStack = new Stack<Exception>();

    // create exception stack
    for (Exception e = exception; e != null; e = e.InnerException)
    {
        exceptionStack.Push(e);
    }

    return exceptionStack;
}

// render stack
private static string GenerateFormattedStackTrace(Stack<Exception> exceptionStack)
{
    StringBuilder trace = new StringBuilder();

    try
    {
        // loop through exception stack
        while (exceptionStack.Count != 0)
        {
            trace.Append("\r\n");

            // render exception type and message
            Exception ex = exceptionStack.Pop();
            trace.Append("[" + ex.GetType().Name);
            if (!string.IsNullOrEmpty(ex.Message))
            {
                trace.Append(":" + ex.Message);
            }
            trace.Append("]\r\n");

            // Load stack trace
            StackTrace stackTrace = new StackTrace(ex, true);
            for (int frame = 0; frame < stackTrace.FrameCount; frame++)
            {
                StackFrame stackFrame = stackTrace.GetFrame(frame);
                MethodBase method = stackFrame.GetMethod();
                Type declaringType = method.DeclaringType;
                string declaringNamespace = "";

                // get declaring type information
                if (declaringType != null)
                {
                    declaringNamespace = declaringType.Namespace ?? "";
                }

                // add namespace
                if (!string.IsNullOrEmpty(declaringNamespace))
                {
                    declaringNamespace += ".";
                }

                // add method
                if (declaringType == null)
                {
                    trace.Append(" " + method.Name + "(");
                }
                else
                {
                    trace.Append(" " + declaringNamespace + declaringType.Name + "." + method.Name + "(");
                }

                // get parameter information
                ParameterInfo[] parameters = method.GetParameters();
                for (int paramIndex = 0; paramIndex < parameters.Length; paramIndex++)
                {
                    trace.Append(((paramIndex != 0) ? "," : "") + parameters[paramIndex].ParameterType.Name + " " + parameters[paramIndex].Name);
                }
                trace.Append(")");


                // get information
                string fileName = stackFrame.GetFileName() ?? "";

                if (!string.IsNullOrEmpty(fileName))
                {
                    trace.Append(string.Concat(new object[] { " in ", fileName, ":", stackFrame.GetFileLineNumber() }));
                }
                else
                {
                    trace.Append(" + " + stackFrame.GetNativeOffset());
                }

                trace.Append("\r\n");
            }
        }
    }
    catch
    {
    }

    if (trace.Length == 0)
    {
        trace.Append("[stack trace unavailable]");
    }

    // return html safe stack trace
    return HttpUtility.HtmlEncode(trace.ToString()).Replace(Environment.NewLine, "<br>");
}
like image 42
Darren Kopp Avatar answered Oct 24 '22 05:10

Darren Kopp