【问题标题】:How to debug a single thread in Visual Studio?如何在 Visual Studio 中调试单个线程?
【发布时间】:2011-07-15 08:30:43
【问题描述】:

我有一些项目的解决方案。在不同的项目中有几个断点。我想跟踪第一个线程遇到了其中一个断点,并继续跟踪该单个线程,尽管其他线程进入了相同的代码块。

我知道这可以通过在断点上定义一个条件来实现,即线程名称 = ... 或线程 ID = ... 但我的情况是一个重负载的 ASP.NET 应用程序,只要我附加到w3wp.exe 很多线程会遇到断点。我需要ThreadLocal<break-point>之类的东西。

有可能吗?如果有,怎么做?

【问题讨论】:

  • @Paolo:这个 Web 应用程序是一个大型 Web 农场的核心,在测试场景中无法模拟错误的情况。
  • 对于 VS 2019 也许你应该试试这个:stackoverflow.com/a/61868591/8579563

标签: c# asp.net multithreading visual-studio-2010 breakpoints


【解决方案1】:

这就是我所做的:

  1. 设置一个条件断点,我 知道只会​​打在线程上 我一直在寻找。

  2. 一旦断点命中并且您处于所需线程中,在 Visual Studio 线程窗口中(调试时,调试 -> 窗口 -> 线程),Ctrl + A(选择所有线程),然后 Ctrl + 单击您当前所在的线程。您应该选择除要调试的线程之外的所有线程。

  3. 右键单击,然后选择“冻结”。

现在,Visual Studio 将只逐步处理解冻的线程。这样做似乎要慢得多,大概是因为它必须遍历所有冻结的线程,但它为我的多线程调试带来了一些理智。

【讨论】:

  • 在我有大约 8 个任务在不同线程中运行的情况下,这对我不起作用。我冻结了所有其他线程并“跳过”,但 IDE 冻结了一段时间,然后跳转到另一个线程。
  • @Diego:我不再从事该项目,但如果它要冻结除一个之外的所有线程,它将改变导致错误的场景,因为线程在错误的情况下是互补的.虽然这是一个优雅的解决方案,但似乎这个功能应该嵌入到 VS 中。
  • @Meta-Knight 你应该冻结所有线程除了主线程。如果你愿意,这个 IDE 不会被冻结
【解决方案2】:

冻结/解冻线程是不正确的方式,因为其他线程不执行任何代码。

最正确和最实用的方法是:

  1. 在断点窗口中按 Ctrl+A(选择所有断点)。
  2. 右键单击并选择“过滤器...”。
  3. 输入“ThreadId=(当前线程 id)”。

Visual Studio 2015 及更高版本中,过程类似:

  1. 在断点窗口中按 Ctrl+A(选择所有断点)。
  2. 右键单击并选择“设置...”。
  3. 检查“条件”并在下拉列表中选择“过滤器”
  4. 输入“ThreadId=(当前线程 id)”。

所以所有线程都被执行,但调试器只命中当前线程。

【讨论】:

  • 这会阻止“Step”调试器命令进入其他线程吗?那是我遇到的一个大问题。我正在单步执行我的线程,突然间我处于完全不相关的代码部分。我不再在 Visual Studio 中开发,所以无法测试。
  • 在断点窗口中右击没有“过滤”命令……你如何找出当前线程ID? -- 你是要去即时窗口并输入System.Threading.Thread.CurrentThread.ManagedThreadId 还是什么?
  • 在我的VS(2015,社区版)中,无法一次修改多个断点的设置。因此过滤器只能一个一个地设置。
  • 我一直有这个问题,我可以发誓在我的上一份工作中,我找到了一个让 Visual Studio 像 Eclipse 一样工作的设置,你会坚持你正在使用的线程,但我找不到它或对它的任何引用。我开始怀疑自己是不是在做梦。
  • -1 因为这仅允许断点,但不能实际调试:单步执行/单步执行不适用于调试单个线程。
【解决方案3】:

我刚刚发布了一个 Visual Studio 2010+ 扩展,它完全符合您的要求。 而且它是免费的:)。

演示文稿

此 Visual Studio 扩展添加了两个快捷方式和工具栏按钮,使开发人员可以在调试多线程应用程序时轻松专注于单线程。

它大大减少了手动进入“线程”窗口以冻结/解冻除需要遵循的线程之外的所有线程的需要,因此有助于提高工作效率。

特点

将进一步的执行限制在当前线程上。将冻结所有其他线程。快捷键:CTRL+T+T 或雪花按钮。 切换到下一个单线程(基于 ID)。将更改当前线程并冻结所有其他线程。快捷键:CTRL+T+J 或下一步按钮。

查看here on the Galleryofficial pageGithub repository

【讨论】:

  • 你用的是哪个版本的VS?
  • 我安装了扩展,但没有成功(对于我当前的项目,我使用 VS2010)。 [顺便说一句,我认为线程变得活跃的问题只是在创建线程时发生,这可能是标准行为,所以我删除了我之前的评论]。
  • 我要去看看这个。你可能是这个星球上唯一一个试图解决微软最大的调试失败之一的人。
  • 唉,它不会安装在 vs2012 上。您是否有更新的版本,或者您愿意分享源代码以便我自己构建它?
  • @stu 源代码在 Codeplex 上:singlethread.codeplex.com 它应该可以在 VS 2012 和 VS 2013 上运行,但我没有更新它(没有人要求它,我自己也没有需要) )。如果你可以让它在 VS 2012+ 上轻松运行并在 Codeplex 上提交,那么我也可以将它推送到 Gallery 上。
【解决方案4】:

如果为 Web 应用程序生成多个线程,@MattFaus 的答案将不起作用。我所做的是以下

  • 设置断点中断我想要的函数中的线程。
  • 一旦线程到达断点并暂停,我删除断点并使用 F8、F10 和 F11 继续调试,以便其他线程可以运行。

【讨论】:

  • 阅读所有热门答案后,此解决方法对我有用。
【解决方案5】:

我使用过的稍微不同的方法:

  1. 创建一个普通断点并让它被命中
  2. 在您的线程窗口中查找您当前正在调试的托管线程 ID
  3. 在断点窗口和选择器过滤器中右键单击断点
  4. 输入 ThreadId=xxx,其中 xxx 是来自 2 的线程 ID
  5. 您现在可以在不停止其他线程且不触发断点的情况下进行调试

这假设您有时间在第二个线程到达您的断点之前执行上述操作。如果没有,并且其他线程在您完成上述操作之前已命中您的断点,您可以在线程窗口中右键单击它们并选择冻结。

【讨论】:

  • +1。 “这假设你有时间......在第二个线程到达你的断点之前”。我将分号包裹在锁中并在分号上放置一个断点。第一次命中断点时,我禁用断点。由于锁,没有其他线程可以进来。 lock(m_someObject) { ; }
  • 为了节省您的 Google,线程窗口位于 Debug > Windows > Threads 下。
【解决方案6】:

在 VS 2019 中:

  1. 在某处设置断点。
  2. 按 F5(继续)直到您的帖子出现。
  3. 单击断点将其删除。
  4. 您可以使用 F10 或 F11 步进线程。

【讨论】:

  • 也适用于 VS2015!
  • 其实你的回答是错误的——这个算法不保证单线程的调试。我不知道您如何使用 F10 和 F11 单线程进行调试,而无需其他线程的额外冻结步骤
  • VS 将跳转到下一个线程...这不起作用
【解决方案7】:

我建议在实时服务器上添加另一个应用程序实例,无论是在同一硬件上还是在新机器上(集群它),然后仅调试该实例。我不会在用户触发的代码中添加断点。如果这不是一个选项,我会添加更多跟踪。

但是,如果这是绝对必要的并且您需要解决方案统计信息,我相信您可以添加一个断点,该断点仅在请求来自您的 IP 地址时才会中断。您可以通过添加检查HttpContext.Request.UserHostAddress 的条件断点来完成此操作。但是请注意,这会大大降低您的应用程序的速度。

【讨论】:

  • 这就是我尝试过的。问题是这个实例不在同一个域上运行(在 IP 或另一个域上运行),这会导致许多证书问题(SSL、WCF、...),而且在低负载下,错误的情况永远不会发生!
  • 对不起,我不确定你尝试过哪些,你试过条件断点吗?
  • 是的,我根据它们的托管 ID 命名它们以确保唯一性。然后很难猜测分配了哪个 Id 并根据猜测设置条件。有时猜测很接近,有时需要很长时间才能捕捉到线索。
【解决方案8】:

如果您不想停止所有其他线程(也许您正在将 Visual Studio 调试器附加到需要响应请求的正在运行的应用程序),您可以使用自动创建和删除断点的宏。

这是在an answer to Stack Overflow question "Step over" when debugging multithreaded programs in Visual Studio 中建议的。

但是,该链接仅说明如何逐行调试。我建议您修改宏(如果您对它感到满意)以使其修改所有断点(例如在给定的行范围内)以仅在当前线程上停止。

【讨论】:

    【解决方案9】:

    我认为这在 Visual Studio 2015 中略有不同。他们更改了断点中的一些内容,但以下是如何应用 hzdbyte 接受的答案(上图):

    在编码边距的断点处,右键单击 > 条件 > 从“条件表达式”更改为“过滤器”。然后,这允许您按 ThreadId 进行过滤。

    或者在断点窗口中的断点上,右键单击>设置>勾选条件框并执行上述操作。

    【讨论】:

      【解决方案10】:

      通过右键单击该行的侧栏来设置断点条件。选择“条件”并输入以下内容,并在引号中加上您的线程名称:

      System.Threading.Thread.CurrentThread.Name=="name_of_your_thread"

      或者,您可以通过从“线程”窗口获取线程的“托管 ID”并使用:

      System.Threading.Thread.CurrentThread.ManagedThreadId==your_managed_thread_id

      【讨论】:

        猜你喜欢
        • 2019-01-28
        • 1970-01-01
        • 2017-05-23
        • 2010-11-07
        • 1970-01-01
        • 2013-01-05
        • 2017-12-01
        • 1970-01-01
        相关资源
        最近更新 更多