c++ - 在 Visual Studio 中调试多线程程序时出现 "Step over"

标签 c++ visual-studio multithreading debugging visual-studio-2005

在 Visual Studio 中调试程序(在我的例子中是 2005 年)时让我烦恼的一件事是,当我使用“step over”(通过按 F10)执行下一行代码时,我经常在与我正在查看的线程完全不同的线程中到达特定的代码行。这意味着我所做的所有上下文都丢失了。

我该如何解决这个问题?

如果在更高版本的 Visual Studio 中可以做到这一点,我也想听听。

在下一行代码上设置一个断点,它有条件只为这个线程中断不是我正在寻找的答案,因为它对我有用的工作太多:)

最佳答案

我认为您的问题只有一个答案,您认为这是“工作量太大”。但是,我相信这是因为您以错误的方式进行操作。让我介绍在线程 ID 上添加条件断点的步骤,这些步骤非常简单,但在您了解它们之前并不明显。

  1. 在您想要继续调试的正确线程中停止调试器(我猜这通常是到达那里的第一个线程)。

  2. 输入 $TID进入监 window 口。

  3. 添加条件为 $TID == < 的断点观察窗口中 $TID 的值 > ,
    示例:$TID == 0x000016a0

  4. 继续执行。

$TID是 Microsoft 编译器(至少从 Visual Studio 2003 开始​​)的魔术变量,它具有当前线程 ID 的值。它比查看 (FS+0x18)[0x24] 容易得多。 =D

话虽如此,您可以通过一些简单的宏获得与调试器的 One-Shot 断点相同的行为。当您跨步时,调试器在幕后设置断点,运行到该断点,然后将其删除。一致的用户界面的关键是在 ANY 断点被命中时删除这些断点。

以下两个宏为当前线程提供Step OverRun To Cursor。这以与调试器相同的方式完成,执行后将删除断点,无论命中哪个断点。

您需要指定一个组合键来运行它们。

NOTE: One caveat -- The Step Over macro only works correctly if the cursor is on the line you want to step over. This is because it determines the current location by the cursor location, and simply adds one to the line number. You may be able to replace the location calculation with information on the current execution point, though I was unable to locate that information from the Macro IDE.

他们来了,祝你好运!

To use these macros in Visual Studio:
1. Open the Macro IDE ( from the Menu, select: Tools->Macros->Macro IDE... )
2. Add a new Code File ( from the Menu: select: Project->Add New Item..., choose Code File, and click Add )
3. Paste in this code.
4. Save the file.

To add key combinations for running these macros in Visual Studio:
1. Open Options (from the Menu, select: Tools->Options )
2. Expand to Environment->Keyboard
3. In Show commands containing:, type Macros. to see all your macros.
4. Select a macro, then click in Press shortcut keys:
5. Type the combo you want to use (backspace deletes typed combos)
6. click Assign to set your shortcut to run the selected macro.

Imports System
Imports EnvDTE
Imports EnvDTE80
Imports System.Diagnostics

Public Module DebugHelperFunctions

    Sub RunToCursorInMyThread()
        Dim textSelection As EnvDTE.TextSelection
        Dim myThread As EnvDTE.Thread
        Dim bp As EnvDTE.Breakpoint
        Dim bps As EnvDTE.Breakpoints

        ' For Breakpoints.Add()
        Dim FileName As String
        Dim LineNumber As Integer
        Dim ThreadID As String

        ' Get local references for ease of use 
        myThread = DTE.Debugger.CurrentThread
        textSelection = DTE.ActiveDocument.Selection

        LineNumber = textSelection.ActivePoint.Line
        FileName = textSelection.DTE.ActiveDocument.FullName
        ThreadID = myThread.ID

        ' Add a "One-Shot" Breakpoint in current file on current line for current thread
        bps = DTE.Debugger.Breakpoints.Add("", FileName, LineNumber, 1, "$TID == " & ThreadID)

        ' Run to the next stop
        DTE.Debugger.Go(True)

        ' Remove our "One-Shot" Breakpoint
        For Each bp In bps
            bp.Delete()
        Next
    End Sub

    Sub StepOverInMyThread()
        Dim textSelection As EnvDTE.TextSelection
        Dim myThread As EnvDTE.Thread
        Dim bp As EnvDTE.Breakpoint
        Dim bps As EnvDTE.Breakpoints

        ' For Breakpoints.Add()
        Dim FileName As String
        Dim LineNumber As Integer
        Dim ThreadID As String

        ' Get local references for ease of use 
        myThread = DTE.Debugger.CurrentThread
        textSelection = DTE.ActiveDocument.Selection

        LineNumber = textSelection.ActivePoint.Line
        FileName = textSelection.DTE.ActiveDocument.FullName
        ThreadID = myThread.ID
        LineNumber = LineNumber + 1

        ' Add a "One-Shot" Breakpoint in current file on current line for current thread
        bps = DTE.Debugger.Breakpoints.Add("", FileName, LineNumber, 1, "$TID == " & ThreadID)

        ' Run to the next stop
        DTE.Debugger.Go(True)

        ' Remove our "One-Shot" Breakpoint
        For Each bp In bps
            bp.Delete()
        Next
    End Sub


End Module

Disclaimer: I wrote these macros in Visual Studio 2005. You can probably use them fine in Visual Studio 2008. They may require modification for Visual Studio 2003 and before.

关于c++ - 在 Visual Studio 中调试多线程程序时出现 "Step over",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/336628/

相关文章:

c++ - Win32 选择/轮询/eof/任何东西?

sql-server - 存储过程 ENCRYPTION 选项取决于构建模式

c - C 中的线程安全 char 字符串

c# - C# 中的 Java WeakHashMap 类是否有等效项?

c++ - 递归函数扫描字符串添加ASCII

visual-studio-2010 - Visual Studio 无法再打开 css 文件

c++ - 为 gmock 自动生成模拟类

c# - 处理多个请求

c++ - 使用 new 运算符初始化数组

没有返回语句的 C++ 返回值