如何从像 Asp.Net 这样的堆栈跟踪中获取“源错误”?

Posted

技术标签:

【中文标题】如何从像 Asp.Net 这样的堆栈跟踪中获取“源错误”?【英文标题】:How can I get the "Source Error" from a stack trace like Asp.Net does? 【发布时间】:2014-03-25 21:36:21 【问题描述】:

我有一个 asp.net 应用程序,如果代码中有异常,我会捕获它,将一些详细信息(堆栈跟踪、异常详细信息等)记录到数据库中,并将参考代码返回给客户端。

我注意到 ASP.Net 黄屏死机在违规行周围显示了几行代码以及堆栈跟踪。

我也想记录那个“源错误:”。 ASP.net 从哪里以及如何获取“Source Error:”源代码?

【问题讨论】:

不抛出新异常。只需使用“抛出”来保留源详细信息。 @Hardrada,不,这不是我要问的。我更新了屏幕截图以突出显示我想要掌握的信息。 附带说明,您必须处于调试模式才能获得源错误,而这在生产系统中是不需要的。 如果没有 PDB 文件,您将无法记录任何源。此外,根据堆栈跟踪,开发人员将能够找到源代码。 看起来.NET框架中负责获取源信息的代码是System.Web.FormatterWithFileInfo.GetSourceFileLines()。基本上它只是打开源文件,然后在错误中找到lineNumber 引用的行,以及前后两行。对于开发人员来说,从您的源代码控制系统中获取相关版本并自己查看可能会更容易。 【参考方案1】:

编辑:如果要错误的文件名和行号,可以这样获取:

var exc = Server.GetLastError();
var frame = new StackTrace(exc, true).GetFrame(0);

var sourceFile = frame.GetFileName();
var lineNumber = frame.GetFileLineNumber();

// sourceFile = c:\path\to\source\file.aspx
// lineNumber = 123

参考:How does ASP.NET get line numbers in it's generic error handler


看起来.NET框架中负责获取源信息的代码是System.Web.FormatterWithFileInfo.GetSourceFileLines()

...
for (int i=1; ; i++) 
    // Get the current line from the source file
    string sourceLine = reader.ReadLine();
    if (sourceLine == null)
        break;

    // If it's the error line, make it red
    if (i == lineNumber)
        sb.Append("<font color=red>");

    // Is it in the range we want to display
    if (i >= lineNumber-errorRange && i <= lineNumber+errorRange) 
        fFoundLine = true;
        String linestr = i.ToString("G", CultureInfo.CurrentCulture);

        sb.Append(SR.GetString(SR.WithFile_Line_Num, linestr));
        if (linestr.Length < 3)
            sb.Append(' ', 3 - linestr.Length);
        sb.Append(HttpUtility.htmlEncode(sourceLine));

        if (i != lineNumber+errorRange)
            sb.Append("\r\n");
    

    if (i == lineNumber)
        sb.Append("</font>");

    if (i>lineNumber+errorRange)
        break;

...

基本上它只是打开源文件,然后在错误中找到lineNumber引用的行,以及前后两行。

【讨论】:

您介意提供reader.ReadLine(); 的值吗(它只是那里的堆栈代码,对吗?)、errorRangelineNumberfFoundLineSR?我想使用它,但那些是我不知道它们来自哪里的值。

以上是关于如何从像 Asp.Net 这样的堆栈跟踪中获取“源错误”?的主要内容,如果未能解决你的问题,请参考以下文章

asp.net求助

启用 ASP.NET 模拟时,异常堆栈跟踪中缺少行号

asp.NET 的update错误,请高人进来看下

ASP.NET - 部署问题 - 通过 Web.Config 启用堆栈跟踪/跟踪侦听器日志以查找内部服务器 500 错误的原因

在发布模式下显示 .NET 程序集的堆栈跟踪中的行号

如何使用 ETW 编写自定义堆栈跟踪