Debug multithreaded applications in Visual Studio
A thread is a sequence of instructions to which the operating system grants processor time. Every process that is running in the operating system consists of at least one thread. Processes that have more than one thread are called multithreaded.
Computers with multiple processors, multi-core processors, or hyperthreading processes can run several simultaneous threads. Parallel processing using many threads can greatly improve program performance, but it may also make debugging more difficult because you're tracking many threads.
Perfect parallel processing is not always possible. Threads sometimes must be synchronized. One thread may have to wait for a result from another thread, or one thread may need exclusive access to a resource that another thread is using. Synchronization problems are a common cause of bugs in multithreaded applications. Sometimes threads may end up waiting for a resource that never becomes available. This results in a condition called deadlock.
Threads and processes
Threads and processes are related concepts in computer science. Both represent sequences of instructions that must execute in a specific order. Instructions in separate threads or processes, however, can execute in parallel.
Processes exist in the operating system and correspond to what users see as programs or applications. A thread, on the other hand, exists within a process. For this reason, threads are sometimes referred to as light-weight processes. Each process consists of one or more threads.
The existence of multiple processes enables a computer to perform more than one task at a time. The existence of multiple threads enables a process to separate work to be performed in parallel. On a computer with multiprocessors, processes or threads can run on different processors. This enables true parallel processing.
Tools for debugging multithreaded apps
Visual Studio provides different tools for use in debugging multithreaded apps.
For threads, the primary tools for debugging threads are the Threads window, thread markers in source windows, the Parallel Stacks window, the Parallel Watch window, and the Debug Location toolbar. To learn about the Threads window and Debug Location toolbar, see Walkthrough: Debug using the Threads window. To learn how to use the Parallel Stacks and Parallel Watch windows, see Get started debugging a multithreaded application. Both topics show how to use thread markers.
For code that uses the Task Parallel Library (TPL) or the Concurrency Runtime, the primary tools for debugging are the Parallel Stacks window, the Parallel Watch window, and the Tasks window, which also supports JavaScript. To get started, see Walkthrough: Debugging a parallel application and Walkthrough: Debugging a C++ AMP application.
For debugging threads on the GPU, the primary tool is the GPU Threads window. See How to: Use the GPU Threads window.
For processes, the primary tools are the Attach to Process dialog box, the Processes window, and the Debug Location toolbar.
Visual Studio also provides powerful breakpoints and tracepoints, which can be useful when you debug multithreaded applications. Use breakpoint conditions and filters to place breakpoints on individual threads. Tracepoints enable you to trace execution of your program without breaking, to study problems such as deadlocks. For more information, see Breakpoint actions and tracepoints.
Debugging a multithreaded application that has a user interface can be especially difficult. You might consider running the application on a second computer and using remote debugging. For more information, see Remote debugging.
The following table shows the information available and the actions you can perform in each of these places:
User Interface | Information Available | Actions You Can Perform |
---|---|---|
Attach to Process dialog box | Available Processes you can attach to: - Process name (.exe) - Process ID number - Menubar Title - Type (Managed v4.0; Managed v2.0, v1.1, v1.0; x86; x64; IA64) - User Name (account name) - Session number |
Select a process to attach to Select a remote computer Change transport type for connecting to remote computers |
Processes window | Attached Processes: - Process Name - Process ID number - Path to process .exe - Menubar Title - State (Break. Running) - Debugging (Native, Managed, and so on.) - Transport type (default, native with no authentication) - Transport Qualifier (remote computer) |
Tools: - Attach - Detach - Terminate Shortcut menu: - Attach - Detach - Detach when debugging stopped - Terminate |
Threads window | Threads in current process: - Thread ID - Managed ID - Category (main thread, interface thread, remote procedure call handler, or worker thread) - Thread Name - Location where thread is created - Priority - Affinity Mask - Suspended Count - Process Name - Flag Indicator - Suspended indicator |
Tools: - Search - Search Call Stack - Flag Just My Code - Flag Custom Module Selection - Group by - Columns - Expand/Collapse callstacks - Expand/Collapse groups - Freeze/Thaw Threads Shortcut menu: - Show threads in source - Switch to a thread - Freeze a running thread - Thaw a frozen thread - Flag a thread for additional study - Unflag a thread - Rename a thread - Show and hide threads Other actions: - View the call stack for a thread in a DataTip |
Source window | Thread indicators in left gutter indicate single or multiple threads (off by default, turned on by using shortcut menu in Threads window) | Shortcut menu: - Switch to a thread - Flag a thread for additional study - Unflag a thread |
Debug Location toolbar | - Current process - Suspend the application - Resume the application - Suspend and shut down the application - Current thread - Toggle current thread flag state - Show only flagged threads - Show only current process - Current stack frame |
- Switch to another process - Suspend, resume, or shut down the application - Switch to another thread in current process - Switch to another stack frame in current thread - Flag or unflag current threads - Show only flagged threads - Show only the current process |
Parallel Stacks window | - Call stacks for multiple threads in one window. - Active stack frame for each thread. - Callers and callees for any method. - Deadlock Detection |
- Filter out specified threads - Filter out external code stacks - Switch to Tasks view - Flag or unflag a thread - Zoom - Copy Stack Frames - Save/Export all stacks as image |
Parallel Watch window | - The flag column, in which you can mark a thread that you want to pay special attention to. - The frame column, in which an arrow indicates the selected frame. - A configurable column that can display the machine, process, tile, task, and thread. |
- Flag or unflag a thread - Display only flagged threads - Switch frames - Sort a column - Group threads - Freeze or thaw threads - export the data in the Parallel Watch window |
Tasks window | - View information about Task objects including task ID, task status (scheduled, running, waiting, deadlocked), and which thread is assigned to the task. - Current location in call stack. - Delegate passed to the task at creation time |
- Switch to current task - Flag or unflag a task - Freeze or thaw a task |
GPU Threads window | - The flag column, in which you can mark a thread that you want to pay special attention to. - The current thread column, in which a yellow arrow indicates the current thread. - The Thread Count column, which displays the number of threads at the same location. - The Line column, which displays the line of code where each group of threads is located. - The Address column, which displays the instruction address where each group of threads is located. - The Location column, which is the location in the code of the address. - The Status column, which shows whether the thread is active or blocked. - The Tile column, which shows the tile index for the threads in the row. |
- Change to a different thread - Display a particular tile and thread - Display or hide a column - Sort by a column - Group threads - Freeze or thaw threads - Flag or unflag a thread - Display only flagged threads |