Как отображает код ASP.NET "Желтый экран смерти"?
Я думал, что код .Net скомпилирован в MSIL, поэтому я всегда задавался вопросом, как Желтые Экраны производят неисправный код. Если он выполняет скомпилированный код, как компилятор может создать код из исходных файлов в сообщении об ошибке?
Не стесняйтесь редактировать этот вопрос/название, я знаю, что это не имеет смысла.
Ответы
Ответ 1
Сборник .Net скомпилирован с метаданными о включенном байт-коде, который позволяет легко декомпилировать код, - как инструменты, такие как .NET Reflector работают, Файлы PDB являются только символами отладки - разница в желтом экране смерти заключается в том, что вы получите номера строк в трассировке стека.
Другими словами, вы получите код, даже если файлы PDB отсутствовали.
Ответ 2
вот так. я сделал несколько изменений, но это довольно близко к тому, что делает 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>");
}
Ответ 3
Я считаю, что файлы pdb, которые выводятся при создании отладки, содержат ссылку на расположение файлов исходного кода.
Ответ 4
Я думаю, что это зависит от отладочной информации, которая может быть включена в скомпилированные сборки.. (хотя я мог определенно ошибаться)
Ответ 5
Я полагаю, что информация, отображающая источник в MSIL, хранится в файле PDB. Если этого нет, то это отображение не произойдет.
Именно этот поиск делает исключение такой дорогостоящей операцией ( "исключения для исключительных ситуаций" ).