我以为.Net代码被编译成MSIL,所以我总是想知道黄色屏幕是如何产生错误的代码的.如果它正在执行已编译的代码,编译器如何能够从错误消息中的源文件生成代码?
随意编辑这个问题/标题,我知道它没有意义.
.Net程序集编译时包含有关所包含字节码的元数据,这些元数据允许轻松反编译代码 - 这就是.Net Reflector等工具的工作方式.PDB文件只是调试符号 - 黄色死亡屏幕的区别在于您将获得堆栈跟踪中的行号.
换句话说,即使PDB文件丢失,您也会获得代码.
像这样.我做了一些改动,但它与ms正在做的非常接近.
// reverse the stack private static StackGenerateExceptionStack(Exception exception) { var exceptionStack = new Stack (); // create exception stack for (Exception e = exception; e != null; e = e.InnerException) { exceptionStack.Push(e); } return exceptionStack; } // render stack private static string GenerateFormattedStackTrace(Stack 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, "
"); }