Visual Studio,调试多个线程中的一个

139

我有一个使用4个线程运行相同代码的应用程序。但是,在调试时,当我进行单步调试时,它会在不同的线程之间跳转。如何将其锁定到一个线程,以便其他线程在调试时被忽略?


你正在使用哪个版本的Visual Studio? Express,Pro,Ultimate..? - Mark
那么jeffamaphone的链接会有所帮助,也许这个链接也能提供更多关于在调试过程中切换到另一个线程的信息:http://msdn.microsoft.com/en-us/library/bb157786.aspx - Mark
请参阅相关讨论:https://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/8543248-make-the-debugger-stick-to-the-current-thread-inst - user626528
7个回答

117

可以。

在线程窗口(Debug -> Windows -> Threads)中,右键单击想要的线程,选择“切换到线程”。

你也可以选择“冻结”不想调试的线程以防止它们运行。但是请不要忘记“解冻”它们,否则它们将无法工作。

更多阅读


33
我有点困惑,答案是“无法做到”吗?问题是如何保持锁定在特定的线程上,这样调试程序时就不会在线程之间跳来跳去。切换到一个线程没问题,但只要另一个线程执行了某些操作,调试器就会跳到那个线程上。如果我不能冻结另一个线程因为它需要执行一些操作,那么我怎样才能保持锁定在我所关心的线程上? - bubbleking
不完整的:| 每次发生什么事情,您都必须始终单击“切换到”。 - Hassan Faghihi
在VS 2022中,有一个“冻结线程”的选项,可以选择并停止所有不需要的线程(_别忘了再次启用它们_)。 - mihkov

19

单步跟踪单个线程在VS 2012中似乎大多已经修复(但仍有一些限制,可以在下面的链接中看到)。断点很麻烦。

冻结和解冻线程是通常的解决方法,正如之前的答案所述,但这很繁琐,当您的线程等待另一个被冻结的线程时,它可能会导致挂起。这些可能很难从中恢复,而不会失去对您感兴趣的线程中的位置。

另一个有用的工作流程是在断点上应用线程过滤器,也在一些答案中提到:

创建断点,右键单击断点,单击“过滤器”,并输入ThreadId = 7740(来自线程窗口的线程ID)。

这可能非常繁琐。

我向微软建议修复单步执行(及其变体),以便永远不切换线程,除非在其他线程中命中显式断点。他们还应该添加一个快捷方式(例如Ctrl-F9)来创建当前线程ID作为其过滤器的断点。这将使第二个工作流程更加方便。

如果您同意此建议将非常有用,请投票赞成,或添加您自己的建议:

https://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/8543248-make-the-debugger-stick-to-the-current-thread-inst


2
在单个线程中逐步执行似乎在VS 2012中已经基本修复了 - 实际上,在VS2017中仍然存在问题。 - user626528

12

您还可以在代码中设置条件断点,并将 thread.Id == [someValue]Thread.Name == "[Somename]" 放入断点条件中...


谢谢Charles,那很有帮助(我不知道你可以这样做)。然而,对我来说最有效的调试方法是jeffamaphone写的方法,因为在它达到断点并查看一些值之前,我不知道它的名称。 - Oskar Kjellin

7
一个更快的解决办法存在于简单情况下——请参考Steve的链接中的评论。
调试器只会在发起步骤的线程上完成步骤。因此,如果您击中断点、禁用它,然后开始步进,您就不应该停在另一个线程上。如果您的应用程序中有其他断点,并且另一个线程击中了其中一个,则您将处于所述的混合线程状态中进行调试。
因此,在我的情况下,一旦各个线程开始击中我的断点,我只需继续几次,直到找到我要查找的调用,然后删除断点并在同一线程上顺利运行代码,而不受其他线程的干扰。
当然,如果您有多个需要保留的断点等等,这就成为了一个问题——但是对于简单的情况来说,这种方法更加容易。

2
步骤5:在单个线程中逐步进行调试,不要跳来跳去
当您调试多线程代码时,您是否经常遇到第一个断点时,执行一步操作,然后突然发现黄色箭头停留在另一个线程上?这种意外行为来自于断点仍然被设置并且因此被触发。默认情况下,调试器会在任何时候都停止在断点处。这意味着,当您执行一步操作时,所有线程都被允许运行,而您当前线程上的步骤尚未完成之前,其中一个正在运行的线程就会在该断点处停止。下次您遇到这种情况,请尝试以下操作:
1. 禁用或删除新线程触发的断点。 2. 按下“继续”(F5)按钮。 3. 观察第一个初始线程上的步骤完成,并且现在是活动调试上下文。 4. 由于您的断点已被删除或禁用,因此您可以继续在该单个线程上进行调试而不会受到干扰。
来源:Visual Studio 中的7个不太知名的调试技巧

2
这非常类似于Visual Studio 2008 SP1中的一个非常相似的问题。它通过一个后期热修复得到了解决。但是还有其他证据表明,这个热修复没有被合并到代码库中,这个反馈项也是一个问题。热修复不被整合回来并不那么罕见。
至少在我能找到的范围内,没有一个反馈项完全描述了你的问题。我建议你提交一个反馈项。考虑到像这样重现错误的常见问题,我强烈建议你包括一个演示此问题的重现项目,并提供如何重现该问题的说明。
对于你的问题,有一种解决方法,你可以进入Debug + Windows + Threads,右键单击你不想调试的线程,然后选择Freeze。别忘了稍后解冻它们。
这些错误在Visual Studio 2010 Service Pack 1中再次得到了修复。

1
我正在使用Visual Studio Professional 2017,并使用线程窗口选择性地冻结和解冻线程。通常情况下,我有多个相同代码的线程,我只想冻结它们,而不是其他线程。实际上,我喜欢MS Threads窗口,因为我可以选择要冻结的一组线程。我按名称对线程进行分组,然后可以冻结所有运行与我调试的相同代码的线程,同时让其余线程继续运行。我尝试过Erwin Mayer扩展,它非常好用,但它会冻结除我正在运行的线程之外的所有线程,有时在调试时不会命中我认为应该命中的断点,因为所有其他线程都停止了,应用程序似乎已经停止。点击暂停按钮并在线程窗口中解冻线程可以解决这个问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接