【问题标题】:How to put breakpoint in every function of .cpp file?如何在 .cpp 文件的每个函数中放置断点?
【发布时间】:2008-10-01 22:20:37
【问题描述】:

有宏吗?要使用哪些 DTE 对象?

【问题讨论】:

  • 我今天看到的最有力的论点是停止在 Windows 下开发并使用带有 gdb 之类的工具的 linux,这些工具可以让您在文件上设置断点。

标签: debugging visual-c++ visual-studio-2005 macros envdte


【解决方案1】:

(这不是你想要的,但差不多:)

您可以在 Visual Studio 中的类的每个成员函数上设置断点,方法是调出 New Breakpoint 对话框并输入:

CMyClass::*

更多详情请见http://blogs.msdn.com/b/habibh/archive/2009/09/10/class-breakpoint-how-to-set-a-breakpoint-on-a-c-class-in-the-visual-studio-debugger.aspx

【讨论】:

    【解决方案2】:

    下面是 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
    

    【讨论】:

    • +1,但不能接受,因为它不适用于命名空间。
    • 如果您在命名空间方面遇到问题,只需注释掉文档开头的第一行。您需要手动将光标放在要切换的块的开头,但它会起作用。
    【解决方案3】:

    我不知道要使用哪些 DTE 函数,但您可以非常简单地录制一个几乎可以做到这一点的宏:

    1. 转到文件顶部
    2. ctrl - shift - R(开始录音)
    3. ctrl - I(增量搜索)
    4. {(搜索第一个 { 字符)。
    5. F9(设置断点)
    6. ctrl - ](转到匹配的 } 字符)
    7. ctrl - shift - R(停止录制)

    现在反复运行(ctrl - shift P 重复)直到到达文件末尾。

    如果您有命名空间,则将 4. 更改为:

    1. ((在函数定义的开头搜索“(”)
    2. esc(停止增量搜索)
    3. ctrl - I(再次增量搜索)
    4. {(函数体开始)

    这种东西可以无限修改以适应你的代码库

    【讨论】:

    • 我有匿名命名空间,可以吗? (暂时没有VS可以查看)
    • 实际上(忽略我之前的评论)它显然会跳过命名空间内的代码。尝试我在中编辑的更改
    • 无法让它在 VS 2010 中工作 - 录制宏时禁用增量搜索。
    【解决方案4】:

    就像康斯坦丁的方法......这似乎是windbg的领域。

    既然你有cpp,(即使你没有,你也可以编写一些东西来解决),使用loggerwindows调试工具的一部分应该没有问题......这是一个非常方便的工具,可惜用的人太少了。

    记录器调试的 C/COM/C++ 轻松,具有丰富的符号信息,挂钩/分析/灵活的仪器;

    One way to activate Logger is to start CDB or WinDbg and attach to a user-mode target application as usual. Then, use the !logexts.logi or !logexts.loge extension command. This will insert code at the current breakpoint that will jump off to a routine that loads and initializes Logexts.dll in the target application process. This is referred to as "injecting Logger into the target application."

    【讨论】:

    • 我一直想了解更多关于这个的信息,我在加载过程中遇到了问题,我想看看这个假设的重复是否发生在一些 google protobuf 异常的上下文中。
    【解决方案5】:

    以下是在 WinDbg 中实现类似功能的方法:

    bm mymodule!CSpam::*
    

    这会在模块mymodule 中的类(或命名空间)CSpam 的每个方法中设置断点。

    我仍在 Visual Studio 中寻找与此功能相近的任何东西。

    【讨论】:

      【解决方案6】:

      有一个宏,但我只用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
      

      【讨论】:

      • 很有趣,虽然我通常不会将 C# 代码放在 .cpp 文件中。我想知道它是否也适用于 C++。
      【解决方案7】:

      这是一种方法(我警告你它很老套):

      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);
      }
      

      【讨论】:

        【解决方案8】:

        把它放在文件的顶部:

        #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
        

        在文件的顶部。

        【讨论】:

        • 我想要一个非侵入式的自动化解决方案。我也可以在每个功能中按 F9。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-22
        • 1970-01-01
        • 1970-01-01
        • 2020-03-21
        • 1970-01-01
        • 2021-04-21
        相关资源
        最近更新 更多