我正在尝试获取行号以创建调试日志,希望通过代码函数调用等更容易地绘制路径
但是,如果我正确使用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
所以我总是得到LineNUmber为0,尽管FrameCount可能是58或者其他什么因为它被调用了什么点。 对sf的反思给出了-sf {ThreadStart在文件中偏移68处:行:列:0:0} System.Diagnostics.StackFrame 并且有一个OFFSET_UNKNOWN标志-1 有一个线程here显示我没有完成的debug_info设置,但是无法在VS社区2013中找到此设置。这是我的困境的原因还是我只是错误地使用它?
因为这仍然没有给我任何有用的信息并且阅读here。我简化了结构,仅用于该方法在那里建议的测试目的,但直接将其移动到我的表单类。
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 所以,如果其他任何人有任何其他东西要向我投掷,我将不胜感激!
谢谢你们!
答案 0 :(得分:1)
虽然FrameCount可能是58
您从自己的代码中移除的距离越远,当帧数为58并且您正在查看底部时,您可能距离它一英里远,CLR可以找到的可能性越小包含所需行号信息的正确PDB文件。例如,它不会包含任何.NET Framework方法的行号信息。
此外,您的编译器默认会为Release版本生成“剥离的”PDB文件。它缺少行号信息。这通常是一件明智的事情,公司倾向于不喜欢将实现细节暴露给窥探者,并且行数通常在Release版本中没用,因为抖动优化器会移动代码。
所以,这基本上是完全正常的。如果您确定它应该显示您自己的代码的行号,那么请注意Project>属性>编译标签>高级>生成调试信息设置。您希望Release配置为“Full”,而不是默认的“pdb-only”。并注意您的部署过程,您必须将PDB与可执行文件一起复制。并且不要过于严肃地对待显示的数字。
答案 1 :(得分: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