【发布时间】:2008-10-01 22:20:37
【问题描述】:
有宏吗?要使用哪些 DTE 对象?
【问题讨论】:
-
我今天看到的最有力的论点是停止在 Windows 下开发并使用带有 gdb 之类的工具的 linux,这些工具可以让您在文件上设置断点。
标签: debugging visual-c++ visual-studio-2005 macros envdte
有宏吗?要使用哪些 DTE 对象?
【问题讨论】:
标签: debugging visual-c++ visual-studio-2005 macros envdte
(这不是你想要的,但差不多:)
您可以在 Visual Studio 中的类的每个成员函数上设置断点,方法是调出 New Breakpoint 对话框并输入:
CMyClass::*
【讨论】:
下面是 1800 INFORMATION 想法的快速实现:
Sub TemporaryMacro()
DTE.ActiveDocument.Selection.StartOfDocument()
Dim returnValue As vsIncrementalSearchResult
While True
DTE.ActiveDocument.ActiveWindow.Object.ActivePane.IncrementalSearch.StartForward()
returnValue = DTE.ActiveDocument.ActiveWindow.Object.ActivePane.IncrementalSearch.AppendCharAndSearch(AscW("{"))
DTE.ActiveDocument.ActiveWindow.Object.ActivePane.IncrementalSearch.Exit()
If Not (returnValue = vsIncrementalSearchResult.vsIncrementalSearchResultFound) Then
Return
End If
DTE.ExecuteCommand("Debug.ToggleBreakpoint")
DTE.ExecuteCommand("Edit.GotoBrace")
DTE.ActiveDocument.Selection.CharRight()
End While
End Sub
【讨论】:
我不知道要使用哪些 DTE 函数,但您可以非常简单地录制一个几乎可以做到这一点的宏:
现在反复运行(ctrl - shift P 重复)直到到达文件末尾。
如果您有命名空间,则将 4. 更改为:
这种东西可以无限修改以适应你的代码库
【讨论】:
就像康斯坦丁的方法......这似乎是windbg的领域。
既然你有cpp,(即使你没有,你也可以编写一些东西来解决),使用loggerwindows调试工具的一部分应该没有问题......这是一个非常方便的工具,可惜用的人太少了。
记录器调试的 C/COM/C++ 轻松,具有丰富的符号信息,挂钩/分析/灵活的仪器;
【讨论】:
以下是在 WinDbg 中实现类似功能的方法:
bm mymodule!CSpam::*
这会在模块mymodule 中的类(或命名空间)CSpam 的每个方法中设置断点。
我仍在 Visual Studio 中寻找与此功能相近的任何东西。
【讨论】:
有一个宏,但我只用c#测试过。
Sub BreakAtEveryFunction()
For Each project In DTE.Solution.Projects
SetBreakpointOnEveryFunction(project)
Next project
End Sub
Sub SetBreakpointOnEveryFunction(ByVal project As Project)
Dim cm = project.CodeModel
' Look for all the namespaces and classes in the
' project.
Dim list As List(Of CodeFunction)
list = New List(Of CodeFunction)
Dim ce As CodeElement
For Each ce In cm.CodeElements
If (TypeOf ce Is CodeNamespace) Or (TypeOf ce Is CodeClass) Then
' Determine whether that namespace or class
' contains other classes.
GetClass(ce, list)
End If
Next
For Each cf As CodeFunction In list
DTE.Debugger.Breakpoints.Add(cf.FullName)
Next
End Sub
Sub GetClass(ByVal ct As CodeElement, ByRef list As List(Of CodeFunction))
' Determine whether there are nested namespaces or classes that
' might contain other classes.
Dim aspace As CodeNamespace
Dim ce As CodeElement
Dim cn As CodeNamespace
Dim cc As CodeClass
Dim elements As CodeElements
If (TypeOf ct Is CodeNamespace) Then
cn = CType(ct, CodeNamespace)
elements = cn.Members
Else
cc = CType(ct, CodeClass)
elements = cc.Members
End If
Try
For Each ce In elements
If (TypeOf ce Is CodeNamespace) Or (TypeOf ce Is CodeClass) Then
GetClass(ce, list)
End If
If (TypeOf ce Is CodeFunction) Then
list.Add(ce)
End If
Next
Catch
End Try
End Sub
【讨论】:
这是一种方法(我警告你它很老套):
EnvDTE.TextSelection textSelection = (EnvDTE.TextSelection)dte.ActiveWindow.Selection;
// I'm sure there's a better way to get the line count than this...
var lines = File.ReadAllLines(dte.ActiveDocument.FullName).Length;
var methods = new List<CodeElement>();
var oldLine = textSelection.AnchorPoint.Line;
var oldLineOffset = textSelection.AnchorPoint.LineCharOffset;
EnvDTE.CodeElement codeElement = null;
for (var i = 0; i < lines; i++)
{
try
{
textSelection.MoveToLineAndOffset(i, 1);
// I'm sure there's a better way to get a code element by point than this...
codeElement = textSelection.ActivePoint.CodeElement[vsCMElement.vsCMElementFunction];
if (codeElement != null)
{
if (!methods.Contains(codeElement))
{
methods.Add(codeElement);
}
}
}
catch
{
//MessageBox.Show("Add error handling here.");
}
}
// Restore cursor position
textSelection.MoveToLineAndOffset(oldLine, oldLineOffset);
// This could be in the for-loop above, but it's here instead just for
// clarity of the two separate jobs; find all methods, then add the
// breakpoints
foreach (var method in methods)
{
dte.Debugger.Breakpoints.Add(
Line: method.StartPoint.Line,
File: dte.ActiveDocument.FullName);
}
【讨论】:
把它放在文件的顶部:
#define WANT_BREAK_IN_EVERY_FUNCTION
#ifdef WANT_BREAK_IN_EVERY_FUNCTION
#define DEBUG_BREAK DebugBreak();
#else
#define DEBUG_BREAK
#endif
然后在每个函数的开头插入 DEBUG_BREAK,如下所示:
void function1()
{
DEBUG_BREAK
// the rest of the function
}
void function2()
{
DEBUG_BREAK
// the rest of the function
}
当您不再需要调试中断时,请注释该行
// #define WANT_BREAK_IN_EVERY_FUNCTION
在文件的顶部。
【讨论】: