Как отображается код желтого экрана смерти ASP.NET?

Я думал, что код .Net компилируется в MSIL, поэтому мне всегда было интересно, как желтые экраны создают ошибочный код. Если он выполняет скомпилированный код, как компилятор может создать код из исходных файлов в сообщении об ошибке?

Не стесняйтесь редактировать этот вопрос / заголовок, я знаю, что это не имеет смысла.


person Kevin    schedule 21.08.2008    source источник


Ответы (5)


Сборка .Net компилируется с включенными метаданными о включенном байт-коде, что позволяет легко декомпилировать код — именно так такие инструменты, как .Net Reflector работает. Файлы PDB — это только символы отладки — отличие желтого экрана смерти в том, что вы получите номера строк в трассировке стека.

Другими словами, вы получили бы код, даже если файлы PDB отсутствовали.

person Greg Hurlman    schedule 21.08.2008

нравится. я сделал несколько изменений, но это довольно близко к тому, что делает ms.

// 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>");
}
person Darren Kopp    schedule 21.08.2008
comment
это из UnhandledErrorFormatter.get_ColoredSquare2Content referencesource.microsoft.com/#System. Интернет/ - person JJS; 01.12.2016

Я считаю, что файлы pdb, которые выводятся при выполнении отладочной сборки, содержат ссылку на расположение файлов исходного кода.

person John Christensen    schedule 21.08.2008
comment
YSOD по-прежнему будет отображать трассировку стека без файлов PDB. - person Greg Hurlman; 20.07.2009

Я думаю, что это связано с отладочной информацией, которая может быть включена в скомпилированные сборки.. (хотя я определенно могу ошибаться)

person Rob Cooper    schedule 21.08.2008

Я считаю, что информация, которая сопоставляет источник с MSIL, хранится в файле PDB. Если этого нет, то сопоставление не произойдет.

Именно этот поиск делает исключение такой дорогостоящей операцией («исключения предназначены для исключительных ситуаций»).

person Nick    schedule 21.08.2008