堆栈跟踪不输出行号 vb.Net

Stack Trace not outputting line numbers vb.Net

我正在尝试获取行号以创建调试日志,希望通过代码函数调用等更轻松地绘制路径

但是,如果我正确使用 StackTrace,它不会给出我需要的响应:

Private Sub FormAnalyser_Load(sender As Object, e As EventArgs) Handles MyBase.Load
...
If isDebug Then LogDebugCall("analyser.vb", "_queryBuilder.Load()")
_queryBuilder.Load()
...
End Sub

在Debugger.vbclass.

Public Shared Sub LogDebugCall(docName As String, callStatement As String)
Debug.Indent()
Debug.Indent()
Debug.Indent()

Dim st As New StackTrace(True)
Dim sf As StackFrame = st.GetFrame(st.FrameCount - 1)
Dim line As String
line = "Line: " & CStr(sf.GetFileLineNumber())

Dim tmp As String 
tmp = sf.GetMethod().Name

Debug.WriteLine(callStatement & Space(50 - Len(callStatement)) & "(Call: " & callStatement & " " & docName & " " & line & ")")
...
End sub

因此,尽管 FrameCount 可能是 58 或其他取决于调用它的时间点,但我总是得到 LineNUber 为 0。 检查 sf 给出 - sf {ThreadStart at offset 68 in file:line:column :0:0 } System.Diagnostics.StackFrame 并且有一个 OFFSET_UNKNOWN 标志 -1 有一个线程 here 显示了 debug_info 的设置,我没有做过,但是在 VS 社区 2013 中找不到这个设置。这是我的问题的原因还是我只是错误地使用它?

因为这仍然没有给我任何有用的东西并且已经阅读 here。我只是为了测试目的简化了结构,该方法在那里建议,但直接将其移至我的表格 class。

Public Sub PrintCurrentLine(ByVal ex As Exception)
    Dim st As StackTrace = New StackTrace(ex)
    Dim sf As StackFrame = st.GetFrame(st.FrameCount - 1)
    Console.WriteLine("Line " & sf.GetFileLineNumber())
End Sub

当没有异常时,异常不适合我想要的,所以

Public Sub PrintCurrentLine()
    Dim st As StackTrace = New StackTrace(true)
    Dim sf As StackFrame = st.GetFrame(st.FrameCount - 1)
    Console.WriteLine("Line " & sf.GetFileLineNumber())
End Sub

无效!两种情况下返回的值 -1 所以我直接在我想捕获的行号的调用方法中声明了 st,sf 并且 sf.GetFileLineNumber() 仍然是 returns -1 因此,如果其他人有任何其他问题可以向我提出,我将不胜感激!

谢谢大家!

although the FrameCount might be 58

你离自己的代码越远,当帧数为 58 而你正在查看底部时,你可能离它一英里远,CLR 可以的可能性越低找到包含所需行号信息的正确 PDB 文件。例如,它不会包含任何 .NET Framework 方法的行号信息。

此外,您的编译器默认会为发布版本生成一个 "stripped" PDB 文件。它缺少行号信息。这通常是明智的做法,公司往往不喜欢将实现细节暴露给窥视者,并且行号通常在发布版本中没有用,因为抖动优化器会四处移动代码。

所以,这大体上是完全正常的。如果您确定它应该显示您自己代码的行号,请注意项目 > 属性 > 编译选项卡 > 高级 > 生成调试信息设置。发布配置需要 "Full",而不是默认的 "pdb-only"。并注意您的部署过程,您必须将 PDB 与可执行文件一起复制。不要把显示的数字看得太严重。

好的,所以我得到了答案,最终获得行号并没有那么困难。我正在每个方法中实现对我的调试器 class 的调用:debugger.MethodIn() 帧 sf 表示带有调试器调用的该方法,而 sfCaller 表示调用该方法的方法。

Dim st As New StackTrace(True)
Dim sf As StackFrame
Dim sfCaller As StackFrame
sf = st.GetFrame(1)
sfCaller = st.GetFrame(2)
col = sfCaller.GetFileLineNumber 
ln = sfCaller.GetFileColumnNumber