【问题标题】:How does the ASP.NET "Yellow Screen of Death" display code?ASP.NET“黄屏死机”如何显示代码?
【发布时间】:2010-09-06 10:03:38
【问题描述】:

我认为 .Net 代码会被编译成 MSIL,所以我一直想知道黄屏是如何产生错误代码的。如果是执行编译后的代码,编译器如何从错误信息中的源文件生成代码?

请随意编辑这个问题/标题,我知道这没有任何意义。

【问题讨论】:

    标签: .net asp.net yellow-screen-of-death


    【解决方案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 文件包含对源代码文件位置的引用。

      【讨论】:

      • YSOD 仍将显示没有 PDB 文件的堆栈跟踪。
      【解决方案4】:

      我认为这取决于编译程序集可以包含的调试信息..(虽然我肯定是错的)

      【讨论】:

        【解决方案5】:

        我相信将源映射到 MSIL 的信息存储在 PDB 文件中。如果这不存在,那么映射将不会发生。

        正是这种查找使异常成为如此昂贵的操作(“异常用于异常情况”)。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-07-23
          • 2011-01-11
          • 2014-03-12
          • 2011-05-14
          • 2010-10-27
          • 2011-06-24
          • 1970-01-01
          • 2011-01-21
          相关资源
          最近更新 更多