0

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

但是,如果我正确使用 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.vb 类中。

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 或其他值,但我总是得到 LineNUMber 为 0,这取决于它在什么时候被调用。检查 sf 给出 - sf {ThreadStart at offset 68 in file:line:column :0:0 } System.Diagnostics.StackFrame 并且有一个 OFFSET_UNKNOWN 标志 -1 这里有一个线程显示debug_info 的设置,我还没有完成,但在 VS 社区 2013 中找不到此设置。这是我遇到问题的原因还是我只是使用错误?

因为这仍然没有给我任何有用的东西并且在这里阅读过。我简化了结构,仅用于该方法建议的测试目的,但直接将其移至我的表单类。

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() 仍然返回 -1 所以如果其他人有其他东西要扔给我,我会很感激!

多谢你们!

4

2 回答 2

1

虽然 FrameCount 可能是 58

您从自己的代码中删除得越远,当帧数为 58 并且您正在查看底部时,您可能离它一英里,CLR 找到合适的 PDB 文件的几率就越低包含所需的行号信息。例如,它不会包含任何 .NET Framework 方法的行号信息。

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

所以,这大体上是完全正常的。如果您确定它应该显示您自己代码的行号,请注意项目 > 属性 > 编译选项卡 > 高级 > 生成调试信息设置。您希望发布配置为“完整”,而不是默认的“仅 pdb”。并注意您的部署过程,您必须将 PDB 与可执行文件一起复制。并且不要太认真地对待显示的数字。

于 2015-06-29T13:34:24.807 回答
0

好的,所以我得到了答案,最终获得行号并不是那么困难。我在每个方法中实现对我的调试器类的调用: 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
于 2015-07-03T12:29:09.580 回答