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

Posted

技术标签:

【中文标题】在发布模式下显示 .NET 程序集的堆栈跟踪中的行号【英文标题】:Display lines number in Stack Trace for .NET assembly in Release mode 【发布时间】:2010-10-12 07:54:49 【问题描述】:

有没有办法在发布模式下构建/部署的 .NET 程序集显示堆栈跟踪中的行?

更新:

我的应用程序分为三个类库项目和一个 ASP.NET“网站”项目。我试图追查的错误是在三个类库项目之一中。我只为生成“对象引用未设置为对象的实例”错误的类库项目部署了 pdb 文件。

堆栈跟踪中仍未显示行号。我是否需要为所有项目部署 pdb 文件以获取堆栈跟踪中的行号?

工作解决方案

为每个应用程序部署 pdb 文件修复了行号问题。

【问题讨论】:

【参考方案1】: 进入要查看堆栈跟踪行号的项目的“属性”窗口。 点击构建“垂直选项卡”。 选择“发布”配置。 检查 DEBUG 常量参数。 取消选中“优化代码”参数以避免内联代码偶尔出现跟踪问题(此步骤不是必需的)。 按 Advanced... 按钮并选择 Output -> Debug Info -> pdb-only。 使用程序集部署生成的 .pdb 文件。

用下面的评论实现:

要检查的另一件事是在“打包/发布 Web”部分中,“排除生成的调试符号”复选框也未选中

【讨论】:

我必须将 pdb 文件与程序集一起部署吗? 是的。这就是调试符号和行号所在的位置。 您可能不想公开此信息,如果您没有必要的话。用它来调试客户端问题,是的。但是您并不总是想要这样做,因为调试信息可能会泄露敏感数据并成为攻击媒介。取决于你的应用是什么。 @Carlo:调试信息也适用于发布(优化)代码,但调试有些受限(***.com/questions/113866)。然而,即使在优化的代码中,调用堆栈也非常可靠,除了内联函数和偶尔会丢失尾调用的情况,因为调用 xxx / ret 序列被替换为 jmp xxx。 要检查的另一件事是在“打包/发布 Web”部分中,“排除生成的调试符号”复选框也未选中【参考方案2】:

在 VS2012 中,您还需要取消选中属性的“打包/发布 Web”部分中的“排除生成的调试符号”。

【讨论】:

或者如果是桌面应用,请确保已部署 PDB 文件【参考方案3】:

我的解决方案

将 pdb 文件复制到与可执行文件相同的文件夹中。

现在我可以在运行exe文件时查看行号了。

这就是原因

http://msdn.microsoft.com/en-us/library/ee416588%28v=vs.85%29.aspx

【讨论】:

【参考方案4】:

我过去曾遇到过一些问题,我觉得需要使用发布版本部署 PDB 文件以跟踪错误。正如你所说,原因是异常发生在一个非常大的方法中,我无法准确确定它发生的位置。

这可能表明该方法需要重构为更小、更细化的方法。不是一刀切的答案,但这种方法在短期(我经常在重构过程中发现错误)和长期对我很有帮助。

只是一个想法。

【讨论】:

这个。当你走的时候,在更粗略的地方以更细的粒度抛出尝试捕获。如果必须做出假设,则在这些函数的开头增加警卫。 经常这么说也是真的,但是,有遗留,有程序员编写新的大方法,有时大方法实际上是最好的做法(拆分它会混淆或 YAGNI)。另外,即使是 5 行方法——你的搜索范围缩小了 5 倍——所以 PDB 在生产中是必不可少的,除非你不甘心使用符号服务器【参考方案5】:

在构建/部署包中包含调试符号。

【讨论】:

【参考方案6】:

在 VS 2008 Express 中,我在 Project Properties --> Compile --> Advanced Compile Options 下找到它。

【讨论】:

你发现了什么?如果您不想发布完整的答案,可以发表评论。【参考方案7】:

在 .NET Core 中,您需要关闭发布模式的“优化代码”选项以显示正确的行号。

C# Compiler Options that control code generation

【讨论】:

【参考方案8】:

这每次都有效。您只需要对堆栈跟踪消息进行子串化。真正的容易!此外,在 vb.net 中,您确实需要执行“显示所​​有文件”并包含 pdb。

'Err is the exception passed to this function

Dim lineGrab As String = err.StackTrace.Substring(err.StackTrace.Length - 5)
Dim i As Integer = 0
While i < lineGrab.Length                   
    If (IsNumeric(lineGrab(i))) Then
        lineNo.Append(lineGrab(i))
    End If
    i += 1
End While

'LineNo holds the number as a string

C#版本:

string lineGrab = error.StackTrace.Substring(error.StackTrace.Length - 5);

int i = 0;
int value;
while (i < lineGrab.Length)

    if (int.TryParse(lineGrab[i].ToString(), out value))
    
        strLineNo.Append(lineGrab[i]);
    
    i++;

【讨论】:

以上是关于在发布模式下显示 .NET 程序集的堆栈跟踪中的行号的主要内容,如果未能解决你的问题,请参考以下文章

如何在不向用户显示堆栈跟踪的情况下处理 servlet 过滤器中的错误状态?

在堆栈跟踪中获取 VB.NET 行号

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

显示正在运行的 Python 应用程序的堆栈跟踪

如何在 asp.net 核心中正确格式化堆栈跟踪信息

在 Spring Boot 应用程序中防止自定义异常的堆栈跟踪日志记录