You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Visual Studio provides several tools and user interface elements to help you debug multithreaded applications. This tutorial shows how to use thread markers, the **Parallel Stacks** window, the **Parallel Watch** window, conditional breakpoints, and filter breakpoints. Completing this tutorial familiarizes you with Visual Studio features for debugging multithreaded applications.
22
22
23
+
::: moniker range=">=vs-2022"
23
24
For tutorials that are more scenario-focused, see the following articles.
24
25
25
26
-[Debug a deadlock using Threads view](../debugger/how-to-use-the-threads-window.md).
26
27
27
28
-[Debug an async application (.NET)](../debugger/walkthrough-debugging-a-parallel-application.md).
29
+
::: moniker-end
28
30
29
31
The first step is to create a multithreaded application project.
30
32
@@ -268,6 +270,9 @@ In the **Parallel Stacks** window, you can switch between a Threads view and (fo
268
270
- A new thread (ontheright) is also starting but is stopped on `ThreadHelper.ThreadStart`.
269
271
::: moniker-end
270
272
273
+
> [!NOTE]
274
+
> For more information on using the **Threads** view, see [Debug a deadlock using the Threads view](../debugger/how-to-use-the-threads-window.md).
275
+
271
276
2. To view the threads in a list view, select **Debug** > **Windows** > **Threads**.
272
277
273
278
::: moniker range=">= vs-2022"
@@ -276,9 +281,6 @@ In the **Parallel Stacks** window, you can switch between a Threads view and (fo
276
281
In this view, you can easily see that thread 20272 is the Main thread and is currently located in external code, specifically *System.Console.dll*.
277
282
::: moniker-end
278
283
279
-
> [!NOTE]
280
-
> For more information on using the **Threads** window, see [Walkthrough: Debug a Multithreaded Application](../debugger/how-to-use-the-threads-window.md).
281
-
282
284
3. Right-click entries in the **Parallel Stacks** or **Threads** window to see the available options on the shortcut menu.
283
285
284
286
You can take various actions from these right-click menus. For this tutorial, you explore more of these details in the **Parallel Watch** window (nextsections).
description: Debug a deadlock in a multithreaded application by using the Threads view of the Parallel Stacks window in the Visual Studio integrated development environment (IDE).
4
-
ms.date: 7/25/2025
4
+
ms.date: 8/19/2025
5
5
ms.topic: how-to
6
6
dev_langs:
7
7
- CSharp
@@ -21,17 +21,25 @@ monikerRange: '>= vs-2022'
21
21
---
22
22
# Debug a deadlock using the Threads view
23
23
24
-
This tutorial shows how to use the **Threads** view of **Parallel Stacks** windows to debug a C# multithreaded application. This window helps you understand and verify the run-time behavior of multithreaded code.
24
+
This tutorial shows how to use the **Threads** view of **Parallel Stacks** windows to debug a multithreaded application. This window helps you understand and verify the run-time behavior of multithreaded code.
25
25
26
-
The Threads view is also supported for C++ and Visual Basic, so the same principles described in this article for C# also apply to C++ and Visual Basic.
26
+
The Threads view is supported for C#, C++, and Visual Basic. Sample code is provided for C# and C++, but some of the content and illustrations apply only to the C# sample code.principles.
27
27
28
28
The Threads view helps you to:
29
29
30
30
- View call stack visualizations for multiple threads, which provides a more complete picture of your app state than the Call Stack window, which just shows the call stack for the current thread.
31
31
32
32
- Help identify issues such as blocked or deadlocked threads.
33
33
34
-
## C# sample
34
+
## Multithreaded call stacks
35
+
36
+
Identical sections of the call stack are grouped together to simplify the visualization for complex apps.
37
+
38
+
The following conceptual animation shows how grouping is applied to call stacks. Only identical segments of a call stack are grouped.
39
+
40
+

41
+
42
+
## Sample code overview (C#, C++)
35
43
36
44
The sample code in this walkthrough is for an application that simulates a day in the life of a gorilla. The purpose of the exercise is to understand how to use the Threads view of the Parallel Stacks window to debug a multithreaded application.
37
45
@@ -46,14 +54,6 @@ To make the call stack intuitive, the sample app performs the following sequenti
46
54
1. Gorilla eats.
47
55
1. Gorilla engages in monkey business.
48
56
49
-
## Multithreaded call stacks
50
-
51
-
Identical sections of the call stack are grouped together to simplify the visualization for complex apps.
52
-
53
-
The following conceptual animation shows how grouping is applied to call stacks. Only identical segments of a call stack are grouped.
54
-
55
-

56
-
57
57
## Create the sample project
58
58
59
59
To create the project:
@@ -64,23 +64,24 @@ To create the project:
64
64
65
65
On the Start window, choose **New project**.
66
66
67
-
On the **Create a new project** window, enter or type *console* in the search box. Next, choose **C#** from the Language list, and then choose **Windows** from the Platform list.
67
+
On the **Create a new project** window, enter or type *console* in the search box. Next, choose **C#**or **C++**from the Language list, and then choose **Windows** from the Platform list.
68
68
69
-
After you apply the language and platform filters, choose the **Console App** for .NET, and then choose **Next**.
69
+
After you apply the language and platform filters, choose the **Console App** for your chosen language, and then choose **Next**.
70
70
71
71
> [!NOTE]
72
72
> If you don't see the correct template, go to **Tools** > **Get Tools and Features...**, which opens the Visual Studio Installer. Choose the **.NET desktop development** workload, then choose **Modify**.
73
73
74
74
In the **Configure your new project** window, type a name or use the default name in the **Project name** box. Then, choose **Next**.
75
75
76
-
For .NET, choose either the recommended target framework or .NET 8, and then choose **Create**.
76
+
For a .NET project, choose either the recommended target framework or .NET 8, and then choose **Create**.
77
77
78
78
A new console project appears. After the project has been created, a source file appears.
79
79
80
-
1. Open the *.cs* code file in the project. Delete its contents to create an empty code file.
80
+
1. Open the *.cs*(or *.cpp*) code file in the project. Delete its contents to create an empty code file.
81
81
82
82
1. Paste the following code for your chosen language into the empty code file.
threads.emplace_back(Gorilla_Start, true); // First gorilla locks tree then banana
264
+
threads.emplace_back(Gorilla_Start, false); // Second gorilla locks banana then tree
265
+
266
+
for (auto& t : threads) {
267
+
t.join();
268
+
}
269
+
return 0;
270
+
}
271
+
```
272
+
194
273
195
274
After you update the code file, save your changes and build the solution.
196
275
@@ -204,6 +283,9 @@ To start debugging:
204
283
205
284
1. On the **Debug** menu, select **Start Debugging** (or **F5**) and wait for the first `Debugger.Break()` to be hit.
206
285
286
+
> [!NOTE]
287
+
> In C++, the debugger pauses in `__debug_break()`. The rest of the code references and illustrations in this article are for the C# version, but the same debugging principles apply to C++.
288
+
207
289
1. Press **F5** once, and the debugger pauses again on the same `Debugger.Break()` line.
208
290
209
291
This pauses in the second call to `Gorilla_Start`, which occurs within a second thread.
@@ -251,6 +333,9 @@ To start debugging:
251
333
252
334
The delay is caused by a deadlock. Nothing appears in the Threads view because even though threads may be blocked you aren't currently paused in the debugger.
253
335
336
+
> [!NOTE]
337
+
> In C++, you also see a debug error indicating that `abort()` has been called.
338
+
254
339
> [!TIP]
255
340
> The **Break All** button is a good way to get call stack information if a deadlock occurs or all threads are currently blocked.
256
341
@@ -260,6 +345,9 @@ To start debugging:
260
345
261
346
The top of the call stack in the Threads view shows that `FindBananas` is deadlocked. The execution pointer in `FindBananas` is a curled green arrow, indicating the current debugger context but also it tells us that the threads are not currently running.
262
347
348
+
> [!NOTE]
349
+
> In C++, you don't see the helpful "deadlock detected" information and icons. However, you still find the curled green arrow in `Jungle.FindBananas`, hinting at the location of the deadlock.
350
+
263
351
In the code editor, we find the curled green arrow in the `lock` function. The two threads are blocked on the `lock` function in the `FindBananas` method.
264
352
265
353
:::image type="content" source="../debugger/media/vs-2022/debug-multithreaded-parallel-stacks-break-all-editor.png" border="false" alt-text="Screenshot of code editor after selecting Break All." lightbox="../debugger/media/vs-2022/debug-multithreaded-parallel-stacks-break-all-editor.png":::
Copy file name to clipboardExpand all lines: docs/debugger/using-the-parallel-stacks-window.md
+8-12Lines changed: 8 additions & 12 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -91,10 +91,10 @@ Icon|Description|
91
91
||Indicates the current location (active stack frame) of the current thread.|
92
92
||Indicates the current location (active stack frame) of a non-current thread.|
93
93
||Indicates the current stack frame (the current debugger context). The method name is bold wherever it appears.|
94
-
||Indicates that the current stack frame has Critical status warning such as Deadlock.|
95
-
||Indicates the deadlocked node.|
96
-
||Indicates that the current stack frame has additional information such as Waiting on, Waiting on lock, owned by, etc. |
97
-
||Indicates that the current task is in blocked/waiting state, etc. |
94
+
||(.NET) Indicates that the current stack frame has Critical status warning such as Deadlock.|
95
+
||(.NET) Indicates the deadlocked node.|
96
+
||(.NET) Indicates that the current stack frame has additional information such as Waiting on, Waiting on lock, owned by, etc. |
97
+
||(.NET) Indicates that the current task is in blocked/waiting state, etc. |
98
98
||Indicates the currently running task.|
99
99
100
100
::: moniker-end
@@ -194,15 +194,13 @@ The following table describes the main features of the **Threads** view:
194
194
::: moniker-end
195
195
196
196
## Tasks view
197
-
If your app uses <xref:System.Threading.Tasks.Task?displayProperty=fullName> objects (managed code) or `task_handle` objects (native code) to express parallelism, you can use **Tasks** view. **Tasks** view shows call stacks of tasks instead of threads.
198
197
199
-
In **Tasks** view:
198
+
For .NET apps using the async/await pattern, the Tasks view is the most helpful for debugging. For a step-by-step tutorial, see [Debug an async application](../debugger/walkthrough-debugging-a-parallel-application.md).
200
199
201
-
- Call stacks of threads that aren't running tasks aren't shown.
202
-
- Call stacks of threads that are running tasks are visually trimmed at the top and bottom, to show the most relevant frames for tasks.
203
-
- When several tasks are on one thread, the call stacks of those tasks are shown in separate nodes.
200
+
In **Tasks** view, you can:
204
201
205
-
To see an entire call stack, switch back to **Threads** view by right-clicking in a stack frame and selecting **Go to Thread**.
202
+
- View call stack visualizations for apps that use the async/await pattern.
203
+
- Identify async code that is scheduled to run but isn't yet running.
206
204
207
205
The following illustration shows the **Threads** view at the top and the corresponding **Tasks** view at the bottom.
208
206
@@ -252,8 +250,6 @@ These video tutorials demonstrate how you can use the Threads and Tasks views of
252
250
253
251
## Related content
254
252
-[Get started debugging a multithreaded application](../debugger/get-started-debugging-multithreaded-apps.md)
255
-
-[Debug an async application (.NET)](../debugger/walkthrough-debugging-a-parallel-application.md)
256
-
-[Debug a deadlock](../debugger/how-to-use-the-threads-window.md)
257
253
-[Switch to Another Thread While Debugging in Visual Studio](../debugger/how-to-switch-to-another-thread-while-debugging.md)
Copy file name to clipboardExpand all lines: docs/debugger/using-the-tasks-window.md
+2-5Lines changed: 2 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -9,15 +9,14 @@ dev_langs:
9
9
- "CSharp"
10
10
- "VB"
11
11
- "FSharp"
12
-
- "C++"
13
12
helpviewer_keywords:
14
13
- "debugger, parallel tasks window"
15
14
author: "mikejo5000"
16
15
ms.author: "mikejo"
17
16
manager: mijacobs
18
17
ms.subservice: debug-diagnostics
19
18
---
20
-
# Using the Tasks Window (C#, Visual Basic, C++)
19
+
# Using the Tasks Window (C#, Visual Basic)
21
20
22
21
The **Tasks** window resembles the **Threads** window, except that it shows information about asynchronous tasks created using the async/await pattern, also called the [Task-based asynchronous pattern (TAP)](/dotnet/standard/asynchronous-programming-patterns/task-based-asynchronous-pattern-tap) instead of thread-based information. Like threads, tasks represent asynchronous operations that can run concurrently; however, multiple tasks may run on the same thread.
23
22
@@ -30,7 +29,7 @@ In .NET code, you can use the **Tasks** window when you work with apps using the
30
29
::: moniker-end
31
30
32
31
> [!TIP]
33
-
> For C/C++ code, the **Threads** view in the **Parallel Stacks** window is typically the most helpful when you need to debug [task groups](/cpp/parallel/concrt/task-parallelism-concurrency-runtime), [parallel algorithms](/cpp/parallel/concrt/parallel-algorithms), [asynchronous agents](/cpp/parallel/concrt/asynchronous-agents), and [lightweight tasks](/cpp/parallel/concrt/task-scheduler-concurrency-runtime). For more information, see [View threads and tasks in the Parallel Stacks window](../debugger/using-the-parallel-stacks-window.md).
32
+
> For C/C++ code, use the **Threads** view in the **Parallel Stacks** window when you need to debug [task groups](/cpp/parallel/concrt/task-parallelism-concurrency-runtime), [parallel algorithms](/cpp/parallel/concrt/parallel-algorithms), [asynchronous agents](/cpp/parallel/concrt/asynchronous-agents), and [lightweight tasks](/cpp/parallel/concrt/task-scheduler-concurrency-runtime). For more information, see [View threads and tasks in the Parallel Stacks window](../debugger/using-the-parallel-stacks-window.md).
34
33
35
34
You can use the **Tasks** window whenever you break into the debugger. You can access it on the **Debug** menu by clicking **Windows** and then clicking **Tasks**. The following illustration shows the **Tasks** window in its default mode.
36
35
@@ -117,8 +116,6 @@ The **Switch to Task** command makes the current task the active task. The **Swi
117
116
118
117
## Related content
119
118
120
-
-[Debug an async application (.NET)](../debugger/walkthrough-debugging-a-parallel-application.md)
121
-
-[Debug a deadlock](../debugger/how-to-use-the-threads-window.md)
122
119
-[First look at the debugger](../debugger/debugger-feature-tour.md)
0 commit comments