在 Visual Studio 中调试多线程程序时“单步执行”

2024-04-07

One thing that annoys me when debugging programs in Visual Studio (2005 in my case) is that when I use "step over" (by pressing F10) to execute to the next line of code, I often end up reaching that particular line of code in a totally different thread than the one I was looking at. This means that all the context of what I was doing was lost.

我该如何解决这个问题?

如果这可以在 Visual Studio 的更高版本中实现,我也想听听。

在下一行代码上设置一个断点,该断点有条件仅中断该线程,这不是我正在寻找的答案,因为这对我来说工作量太大了:)


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

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

  2. Enter $TID进入监视窗口。

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

  4. 继续执行。

$TID是 Microsoft 编译器(至少从 Visual Studio 2003 起)的一个神奇变量,它具有当前线程 ID 的值。它比查看 (FS+0x18)[0x24] 更容易。 =D

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

下面两个宏提供跨过 and 运行到光标处对于当前线程。这是以与调试器相同的方式完成的,无论命中哪个断点,执行后都会删除断点。

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

NOTE: 一个警告——跨过仅当光标位于要跳过的行上时,宏才能正常工作。这是因为它通过光标位置确定当前位置,并简单地将行号加一。您也许可以用当前执行点的信息替换位置计算,尽管我无法从宏 IDE 中找到该信息。

他们在这里,祝你好运!

要在 Visual Studio 中使用这些宏:
1. 打开宏 IDE(从菜单中选择:工具->宏->宏 IDE... )
2. 添加新的代码文件(从菜单中:选择:项目->添加新项目..., 选择代码文件,然后单击Add )
3. 粘贴此代码。
4. 保存文件。

要添加用于在 Visual Studio 中运行这些宏的组合键:
1. 打开选项(从菜单中选择:工具->选项 )
2. 扩展至环境->键盘
3. 在显示包含以下内容的命令:, type Macros.查看所有宏。
4. 选择一个宏,然后单击按快捷键:
5. 输入您要使用的组合(退格键删除键入的组合)
6.点击Assign设置运行所选宏的快捷方式。

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

免责声明:我在中编写了这些宏视觉工作室2005。你也许可以很好地使用它们视觉工作室2008。他们可能需要修改视觉工作室2003和之前。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Visual Studio 中调试多线程程序时“单步执行” 的相关文章

随机推荐