如何在 Visual Studio 中调试单线程?

发布于 2024-10-22 02:19:42 字数 343 浏览 2 评论 0 原文

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

我知道这可以通过在断点上定义一个条件来实现,即线程名称 = ... 或线程 Id = ... 但我的情况是负载较重 ASP.NET 应用程序,一旦我附加到 w3wp.exe,许多线程就会遇到断点。我需要像 ThreadLocal 这样的东西。

是否可以?如果是这样,怎么办?

I have a solution with some projects. There are several break-points in different projects. I want to trace the first thread hit one of these break-points and continue tracing that single thread despite of other threads entering the same code-blocks.

I know this is possible through defining a condition on the break-point, that is, thread name = ... or thread Id = ... but my case is a heavy loaded ASP.NET application and as soon as I attach to w3wp.exe many threads will hit the break-points. I need some thing like a ThreadLocal<break-point>.

Is it possible? If so, how?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(14

dawn曙光 2024-10-29 02:19:42

这就是我所做的:

  1. 设置一个条件断点,我
    知道只会​​击中线索
    我正在寻找的。

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

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

现在,Visual Studio 将仅单步执行解冻的线程。这样做时似乎要慢得多,大概是因为它必须循环所有冻结的线程,但它给我的多线程调试带来了一些理智。

Here's what I did:

  1. Set a conditional break point that I
    knew would only hit on the thread
    that I was looking for.

  2. Once the breakpoint hits and you are in the thread you want, in the Visual Studio Threads window (while debugging, Debug -> Windows -> Threads), Ctrl + A (to select all threads), and then Ctrl + click the thread you are currently on. You should have all threads except the one you want to debug selected.

  3. Right-click, and choose "Freeze".

Now, Visual Studio will only step through the thawed thread. It seems to be much slower when doing this, presumably because it has to loop through all of the frozen threads, but it brought some sanity to my multi-threaded debugging.

想念有你 2024-10-29 02:19:42

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

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

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

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

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

因此所有线程都被执行,但调试器仅命中当前线程。

Freeze/Thaw threads is an incorrect way because other threads don't execute any code.

The most correct and usable way is to:

  1. Hit Ctrl+A in the breakpoints window (select all breakpoints).
  2. Right click and select "Filter...".
  3. Enter "ThreadId=(current thread id)".

In Visual Studio 2015 and newer, the process is similar:

  1. Hit Ctrl+A in the breakpoints window (select all breakpoints).
  2. Right click and select "Settings...".
  3. Check "Conditions" and select "Filter" in the dropdown
  4. Enter "ThreadId=(current thread id)".

So all threads are executed, but the debugger hits on the current thread only.

意中人 2024-10-29 02:19:42

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

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

If multiple threads are being spawned as for a web application, @MattFaus answer's will not work. what I did instead is the following

  • Set up a breakpoint to interrupt the thread in the function I want.
  • Once the thread gets to the breakpoint and is paused, I remove the breakpoint and continue debugging using F8,F10 and F11, so that the others threads can run.
音盲 2024-10-29 02:19:42

我刚刚发布了一个 Visual Studio 2010+ 扩展,它完全可以满足您的需求。
而且它是免费的:)。

演示

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

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

功能

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

请访问此处的图库官方页面Github 存储库

I have just released a Visual Studio 2010+ extension that does exactly what you are looking for.
And it's free :).

Presentation

This Visual Studio extension adds two shortcuts and toolbar buttons to allow developers to easily focus on single threads while debugging multi-threaded applications.

It dramatically reduces the need to manually go into the Threads window to freeze/thaw all threads but the one that needs to be followed, and therefore helps improve productivity.

Features

Restrict further execution to the current thread only. Will freeze all other threads. Shortcut: CTRL+T+T or Snowflake button.
Switch to the next single thread (based on ID). Will change current thread and freeze all other threads. Shortcut: CTRL+T+J or Next button.

Check it out here on the Gallery, on the official page or the Github repository.

依 靠 2024-10-29 02:19:42

我使用的方法略有不同:

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

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

A slightly different approach which I've used:

  1. Create a normal breakpoint and let it get hit
  2. Look in your threads window for the managed thread ID that you're current debugging
  3. Right click your breakpoint in the breakpoints window and selecter filter
  4. Enter ThreadId=xxx where xxx is the thread ID from 2
  5. You can now debug without stopping other threads and without them hitting your breakpoint

This assumes you have time to do the above before a second thread hits your breakpoint. If not and other threads hit your breakpoint before you've done the above you can right click them in the threads window and choose freeze.

雨落□心尘 2024-10-29 02:19:42

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

System.Threading.Thread.CurrentThread.Name==“name_of_your_thread”

或者,您可以通过从“线程”获取线程的“托管 ID”来执行相同操作窗口及使用:

System.Threading.Thread.CurrentThread.ManagedThreadId==your_driven_thread_id

Set a Breakpoint Condition by right clicking the side bar of the line. Select "Condition" and enter the following with the name of your thread in quotes:

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

Alternatively you can do the same by getting the thread's "Managed ID" from the "Threads" Window and use:

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

攀登最高峰 2024-10-29 02:19:42

在 VS 2019 中:

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

In VS 2019:

  1. Set a breakpoint somewhere.
  2. Hit F5 (Continue) until your thread comes.
  3. Click on breakpoint to remove it.
  4. You can step the thread with F10 or F11.
爱格式化 2024-10-29 02:19:42

在VS2019中,条件断点为tid == xxxxx
这样断点只会在该线程上被命中

in VS2019, the conditional breakpoint is tid == xxxxx
this way the breakpoint will be hit only on that thread

有木有妳兜一样 2024-10-29 02:19:42

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

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

I would suggest adding another instance of the application on the live server, either on the same hardware or a new machine (cluster it) and then debug only that instance. I wouldn't add a breakpoint in code users are triggering. If that's not an option, I'd add more tracing.

However, if this is absolutely necessary and you need a solution stat, I'm sure you could add a breakpoint that breaks only if the request is coming from your IP address. You would do this by adding a conditional breakpoint that inspects HttpContext.Request.UserHostAddress. Note however that this slows down your application considerably.

三生路 2024-10-29 02:19:42

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

这是在对 Stack Overflow 问题的回答中建议的在 Visual Studio 中调试多线程程序时“跳过”

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

If you don't want to stop all other threads (maybe you are attaching Visual Studio debugger to a running application that needs to answer to requests), you can use a macro that create and remove breakpoints automatically.

This is suggested in an answer to Stack Overflow question "Step over" when debugging multithreaded programs in Visual Studio.

However, the link only explain how to debug line by line. I suggest you modify the macro (if you're comfortable with it) to make it modify all breakpoints (in a given range of line for instance) to stop only on the current thread.

溺深海 2024-10-29 02:19:42

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

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

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

I think this is slightly different in Visual Studio 2015. They've changed a few things in the breakpoints, but here's how to apply the accepted answer from hzdbyte (above):

On the breakpoint in the coding margin, Right-Click > Conditions > Change from 'Conditional Expression' to 'Filter'. This then allows you to filter by ThreadId.

Alternatively on the breakpoint in the Breakpoints window, Right-Click > Settings > tick the Conditions box and do the above.

木緿 2024-10-29 02:19:42

您可以使用这个新的扩展,它可能会有所帮助。

https://marketplace.visualstudio.com/items?itemName=vsdbgplat.StickToThread

此扩展向 Visual Studio 2022+ 添加了“Stick to Thread”模式。当最初单击“坚持线程”按钮时,它将模式切换为“打开”,并且除当前线程之外的所有线程都被冻结。这使得调试单线程变得很容易。

You can use this new extension which might help.

https://marketplace.visualstudio.com/items?itemName=vsdbgplat.StickToThread

This extension adds a "Stick to Thread" mode to Visual Studio 2022+. When the "Stick to Thread" button is clicked initially, it toggles the mode to "on" and all threads except the current thread are frozen. Which makes it easy to debug single thread.

蛮可爱 2024-10-29 02:19:42

TL;博士;跳到错误的线程时按F5即可。

我正在 Visual Studio Pro 2022 Preview 中调试多线程队列处理器,我在每个正在处理的队列项都会命中的点放置了一个断点。 IDE 由于遇到断点而暂停。我按 F10(单步执行)几次来逐步执行代码。然后另一个线程遇到了断点,IDE 将我弹出到该线程。我按了 F5(继续)。第二个线程继续处理,黄色调试线返回到我原来的线程。

TL;DR; Just press F5 when it jumps to the wrong thread.

I'm debugging a multithreaded queue processor in Visual Studio Pro 2022 Preview, I placed a breakpoint at a point where each queue item being processed would hit it. The IDE pauses because it hit the breakpoint. I press F10 (Step Over) a few times to step through the code. Then the another thread hit the breakpoint, and the IDE popped me over to that thread. I pressed F5 (Continue). The second thread continued processing, and the yellow debug-line returned to my original thread.

秋叶绚丽 2024-10-29 02:19:42

全选、右键单击、冻结方法在 VS-2022 中不再有效 - 右键单击​​会将选择重置为一个列表项。

关于“更好”的解决方案,它们取决于用例,并不总是“最好”。

就我而言,线程运行相同的代码,并且“应该”并行运行,没有跨线程影响。至少一个线程中有一些独特/不确定的东西,我需要单步执行该单个线程,并冻结所有其他线程,以找出导致不确定性的原因。

仅隔离一个线程就可以解决问题。

在某些奇怪的用例中,冻结所有其他线程是该用例中的最佳选择 - 但我认为没有办法做到这一点。

我可以完成这项工作,但这非常乏味且耗时。 “冻结所有其他线程”现在会很方便。

The select all, right click, freeze approach no longer works in VS-2022 - right click resets the selection to one list item.

Regarding the "better" solutions, they are use case dependent and not always "best."

In my case, the threads are running identical code and "should be" running in parallel with no cross thread effects. There is something unique/non deterministic in at least one thread and I need to single step through that single thread, with all other threads frozen, to find what's causing the nondeterminism.

Isolating only one thread causes the problem to go away.

There are odd use cases where freezing all other threads is the best choice in that use case - but I see no way to do it.

I can get the job done, but it's very tedious and time consuming. "Freezing All Other Threads" would be handy right now.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文