如何让在.NET中抛出的异常的StackTrace中显示行号?

40

Exception类的StackTrace属性是什么?MSDN对此进行了解释:

StackTrace属性保存着一段堆栈跟踪信息,可以用来确定错误发生在代码中的哪个位置。堆栈跟踪会列出所有在异常之前被调用的方法以及这些调用在源代码中的行号。

因此我知道该信息是可用的。那么如何让行号实际显示在堆栈跟踪中呢?我的代码在一个非常复杂的、经过大量对象处理的部分中抛出了异常,所以我不想逐步执行很多次来查看异常发生的位置。异常的堆栈跟踪只显示了方法签名而没有行号。


如果您正在调试代码,可以在“调试”菜单中告诉Visual Studio在异常处中断。 - Jason Goemaat
3
如果我知道抛出异常的代码行号,我就可以这样做。 - Christopher Perry
6个回答

48
要在StackTrace中获取行号,需要将正确的调试信息(PDB文件)与您的dlls/exes一起使用。要生成调试信息,请在项目属性->生成->高级->调试信息选项中设置:

alt text

将其设置为full应该就足够了(有关其他选项的详细信息,请参见高级生成设置对话框文档)。默认情况下,Debug构建配置会生成调试信息(即PDB文件),但也可以为Release构建配置生成调试信息。

为发布版本生成PDB文件使您能够在不包含PDB文件的情况下分发代码,但如果您需要行号(甚至附加远程调试器),则可以将PDB文件放在dll旁边。请注意,在发布版本中,由于编译器或JIT编译器所做的优化,行号可能不完全正确(特别是如果行号显示为0)。


1
MSDN表示,除非您设置/debug:full,否则无法进行远程调试。我想知道这是否意味着如果您设置了/debug:full,即使没有源代码,也可以附加和调试源代码,而/debug:pdbonly仅在您拥有源代码并且不介意偶尔出现执行点错误的情况下就足够了。 - axk
14
似乎没有生效,我已经将其设置为全屏但是堆栈跟踪中没有行号。 - msbg
2
@msbg - 1). 你确定你针对调试和发布版本都进行了设置吗?2). 行号只会显示你的代码... 就像这样:my_code.temp.cmdBoom_Click(Object sender, EventArgs e) in TestApp\test.aspx.cs:line 1245 at System.Web.UI.WebControls.Button.OnClick(EventArgs e) at System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) at System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) ... 另外,你取消了“优化代码”的勾选吗? - mike
@mike 谢谢你展示了它将在路径的末尾。你能把它加到你的答案里吗? - Jared Beach
需要注意的是,在通过VSCode进行.NET Core项目开发时,您可以通过向.csproj文件中添加<PropertyGroup><DebugType>Full</DebugType></PropertyGroup>来实现与上述方法相同的效果。我的日志现在显示行号而不是0。 - Chris Altig
你需要对所有项目文件(包括 .dll 输出)进行操作,而不仅仅是顶层项目(通常为 .exe)。 - Brains

7
如果您有一个使用VS2012或更高版本的web应用程序或Web服务项目,则更改构建设置将无效。相反,您应该遵循本文中的建议:
请参阅Visual Studio 2012网站发布不复制.pdb文件 具体来说,您应该在以下设置中包含:
<YOUR_PROJECT>\Properties\PublishProfiles\*.pubxml

您项目的文件:

<PropertyGroup>
  <ExcludeGeneratedDebugSymbol>False</ExcludeGeneratedDebugSymbol>
</PropertyGroup>

如果您正在使用MSBuild,例如使用Package配置和Web Deploy,您可以将相同的<PropertyGroup>元素添加到Web项目的*.csproj*文件中。 - Kenny Evitt

7
假设有一个装配的 pdb 文件,您可以尝试以下操作:
try
{
    throw new Exception();
}
catch (Exception ex)
{
    // Get line number from the stack trace's top frame for the exception with source file information
    int linenumber = (new StackTrace(ex, true)).GetFrame(0).GetFileLineNumber();
}

6

您需要启用pdb文件构建项目,并确保将pdb文件与应用程序一起部署。您可以通过右键单击需要pdb文件的程序集,然后转到“属性”>“生成”>“高级”来检查是否为您的配置构建了pdb文件,并确保在“输出调试信息”下设置为full。


5
我的PDB文件已经在那里了,而且一切都设置得很好。但仍然无法进行。 - Christopher Perry

1
除了其他很好的建议,我们正在部署到IIS。我们有一个暂存服务器和一个生产服务器。它们看起来完全相同,除了暂存服务器可以给我们提供行号,而生产服务器则不能。事实证明,在生产的bin目录中有一个额外的DLL(顺便说一下,它是SqlServerSpatial.dll),一旦将其移动到系统目录,行号就开始在生产环境中出现了。
教训是确保生产环境的bin目录与开发环境的bin目录在每个方面都匹配(除了XML文件)。

-11
似乎找到了解决方案。 至少在VS2010上,当Output Debug Info设置为full时,我也没有在异常中看到行号。看起来诀窍是在编辑器中打开行号。(工具->选项->文本编辑器->所有语言->常规->显示->行号) 现在异常会显示出行号。

5
这是显示代码行号,而不是堆栈跟踪中的行号。 - RemarkLima

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接