“步骤”当在Visual Studio中调试多线程程序 [英] "Step over" when debugging multithreaded programs in Visual Studio

查看:181
本文介绍了“步骤”当在Visual Studio中调试多线程程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Visual Studio中调试程序时(我的例子中的2005),有一件事让我恼火的是,当我使用step over(通过按 F10 )执行到下一行代码时,我经常最终到达那个特定的代码行在一个完全不同的线程,比我所看到的。



如何解决这个问题?



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



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

解决方案

我认为你的问题只有一个答案,你的折扣是太多的工作。但是,我相信这是因为你是错误的方式。让我介绍在线程ID上添加条件断点的步骤,这是非常容易的,但是直到你知道它们才不明显。


  1. 在调试器正确的线程中停止调试器,
  2. 在观察窗口中输入 $ TID


  3. 具有条件 $ TID ==< 从观察窗口$ TID的值的断点 >
    示例 $ TID == 0x000016a0


  4. 继续执行。


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



话虽如此,你可以得到与调试器的单点断点一样简单的宏的相同行为。当你跳过,调试器,在幕后,设置断点,运行到该断点,然后删除它。一致的用户界面的关键是在任何断点被触发时删除这些断点。



以下两个宏提供 / em>和运行到游标。这是以与调试器相同的方式完成的,其中断点在执行后被删除,而不管命中了哪个断点。



您将要分配一个组合键

:一个警告 - 如果光标在您要跳过的行上,则
宏只能正常工作。这是因为它通过光标位置确定当前位置,并且简单地向行号添加一个。您可以使用当前执行点的信息替换位置计算,但我无法从宏IDE中找到该信息。


在Visual Studio中使用这些宏:



1.打开宏IDE(从菜单中选择工具 - >宏 - >宏IDE ...

2。添加新的代码文件(从菜单:选择:项目 - >添加新项... ,选择代码文件,然后点击< )

3.粘贴此代码。

4.保存该文件。



添加在Visual Studio中运行这些宏的组合键:

1.打开选项(从菜单中选择工具 - >选项
$
2.展开到环境 - >键盘

3.在显示包含的命令中,键入 宏。 可查看您的所有宏。

4.选择一个宏,然后点击 5.键入要使用的组合(退格删除已输入的组合

6.单击分配设置快捷方式以运行所选的宏。




 导入系统
导入EnvDTE
导入EnvDTE80
Imports System.Diagnostics

公共模块DebugHelperFunctions

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

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

获取本地引用以方便使用
myThread = DTE.Debugger.CurrentThread
textSelection = DTE.ActiveDocument.Selection

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

'添加单次断点当前线程的当前文件
bps = DTE.Debugger.Breakpoints.Add(,FileName,LineNumber,1,$ TID ==& ThreadID)

'运行到下一个停止
DTE.Debugger.Go(True)

'删除我们的单次断点
每个bp在bps
bp.Delete()
下一个
结束子

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

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

获取本地引用以便于使用
myThread = DTE.Debugger.CurrentThread
textSelection = DTE。 ActiveDocument.Selection

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

'在当前行的当前文件中为当前线程添加一个单次断点
bps = DTE.Debugger.Breakpoints.Add(,FileName,LineNumber,1,$ TID ==& ThreadID)

'运行到下一个停止
DTE.Debugger.Go(True)

'删除我们的单次断点
每个bp在bps
bp.Delete()
下一个
结束子


结束模块




免责声明:我在Visual Studio 2005中编写了这些宏。您可以在 Visual Studio 2008 中使用它们。他们可能需要修改 Visual Studio 2003 及之前的版本。



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.

How do I work around this?

If this is possible to do in later versions of Visual Studio, I'd like to hear about it as well.

Setting a breakpoint on the next line of code which has a conditional to only break for this thread is not the answer I'm looking for since it is way too much work to be useful for me :)

解决方案

I think there is only one answer to your question, which you have discounted as being 'way too much work.' However, I believe that is because you are going about it the wrong way. Let me present steps for adding a conditional breakpoint on Thread ID, which are extremely easy, but not obvious until you know them.

  1. Stop the debugger at a point where you are in the correct thread you want to continue debugging in (which I would guess is usually the first thread that gets there).

  2. Enter $TID into the watch window.

  3. Add a break point with the condition $TID == <value of $TID from Watch Window>,
    Example: $TID == 0x000016a0

  4. Continue Execution.

$TID is a magic variable for Microsoft compilers (since at least Visual Studio 2003) that has the value of the current Thread ID. It makes it much easier than looking at (FS+0x18)[0x24]. =D

That being said, you can get the same behavior as the debugger's One-Shot breakpoints with some simple macros. When you step over, the debugger, behind the scenes, sets a breakpoint, runs to that breakpoint and then removes it. The key to a consistent user interface is removing those breakpoints if ANY breakpoint is hit.

The following two macros provide Step Over and Run To Cursor for the current thread. This is accomplished in the same manner as the debugger, with the breakpoints being removed after execution, regardless of which breakpoint is hit.

You will want to assign a key combination to run them.

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.

Here they are and good luck bug hunting!!

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.

这篇关于“步骤”当在Visual Studio中调试多线程程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆