带有错误行号的堆栈跟踪

12
为什么堆栈跟踪会显示“line 0”,但只在堆栈跟踪的一个帧中
例如。
...
at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
at System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader()
at My.LibraryA.Some.Method():line 16
at My.LibraryB.Some.OtherMethod():line 0
at My.LibraryB.Some.Method():line 22
at My.LibraryA.Some.Method():line 10

背景:

我的应用程序出现了异常并记录了一个堆栈跟踪到其日志文件中。在构建应用程序时,所有程序集都使用完整的调试信息编译(项目属性->生成->高级->调试信息->完整),因此生成了PDB文件。为了帮助我诊断错误的来源,我将PDB文件放入应用程序的bin目录中,并重现了这个异常。每个堆栈帧的所有行号看起来都是正确的,除了其中一个显示其源代码为“line 0”。


它是使用优化编译的吗?(请记住,优化开/关和调试信息开/关是正交开关。)如果是这样,那么即时编译器可能会选择进行内联或其他优化,这可能会使原始代码难以确定位置。 - Eric Lippert
@Eric:是的,确实是这样。有没有办法获取“out”的实际行号? - adrianbanks
3
当然。关闭优化后编译它。 - Eric Lippert
9
还要注意的是,如果Jitter可以进行尾递归,抖动会允许优化掉调用堆栈帧。一个很重要但被很多人忽视的事实是:调用堆栈并不能告诉你调用来自哪里,它只能告诉你控制权将去哪里。通常情况下,通过知道控制权将去哪里,你可以推断出调用来自哪里,但如果Jitter可以在不保留关于调用来源的信息的情况下找到控制权将去哪里,那么它就可以这样做。 - Eric Lippert
1个回答

5

正如Eric所建议的那样,这确实是由于方法内联导致的。

我设法在本地复现了原始错误,但只有在 release 构建时才会出现。由于我有 PDBs,因此可以逐步执行代码并找到问题。


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