Parallel Stacks – Tasks view

Wed, May 27, 2009, 04:12 PM under ParallelComputing
This post was UPDATED for the VS2010 Beta 2 release

This blog post presumes you read my posts on Parallel Tasks and on Parallel Stacks, which describe the usefulness of the new VS2010 debugger windows for debugging multithreaded applications. In today's post I'll expand on the task-specific support in the Parallel Stacks window: we call this the Tasks View of the Parallel Stacks window and you can switch to that view from the combobox in the toolbar.


Threads versus Tasks
For the purposes of this window, there are 3 main differences when you are looking at call stacks of threads versus call stacks of tasks:

1. Some threads in your application will be running tasks and others will not.
2. A thread could be running more than 1 Task (only the task at the top part of the thread's call stack is actually running, you can assert that the other(s) would be in a waiting state).
3. Call stacks of threads are mapped back to the thread via the Thread ID; call stacks of tasks should be mapped back to the task via the Task ID.

These 3 differences map to the following 3 observations of what you see in the Tasks View of the Parallel Stacks window (compared to the separately covered Threads View of the Parallel Stacks window):

a) We don’t show the threads not executing tasks.
b) We split call stacks of threads executing multiple tasks into separate nodes, so you can clearly see each task call stack separately.
c) The tooltip of the header in the node and on each method context (displaying the stack frames) shows task IDs instead of thread IDs.

Here is an example where one thread is not running tasks (the Main thread):


Trimming frames from the bottom
You will notice in the screenshot above another difference not mentioned so far: some stack frames at the root of the call stack are trimmed. This is what I call showing the "real" call stacks of tasks. If you think about it, your code created a task pointing it to a method and it is from somewhere close to that method that you want to start looking at the call stack. All the other (typically non-user code) stack frames at the root of the thread's call stack are not of interest in this Tasks View, so we trim them out (as per screenshot above).

Trimming frames from the top
We also trim stack frames from the top of the call stack. The consistent decision could have been to trim *all* non-user code at the top since that is not code you would typically care too much about when debugging tasks. However, what is interesting in many scenarios is the first non-user method that was called from the top most user frame – so we kept that one frame and trimmed all the ones above it.

Here is an example of trimming stack frames from the top and also of a thread running 2 tasks:


"Go To Thread" and "Go To Task" menu
Before anyone panics with the stack trimming I mentioned above, remember that you can always view entire thread call stacks in this window by switching to the Threads View. In fact, we made it even easier to switch not just view, but also scroll to the exact position you want by offering a menu item (you'll recall I left that out from my context menu description last time) that switches views and scrolls to the same stack frame you are looking in the other view.

Header Icon
The header of each node shows the count of Threads or Tasks depending on the view we are on (default Threads View or Tasks View). In Tasks View, it also shows the task Status icon if a task's topmost frame ends in that node. You can see that in the previous screenshot: the node with 1 running task has the running icon; the two nodes each with a waiting task have the waiting icon; the node with 2 tasks has none that "end" in that box, so it shows no icon in the header.

Header tooltip
I mentioned the method context tooltip showing task IDs instead of thread IDs and you can see that in the screenshot below. I also mentioned the header tooltip showing task IDs instead of thread IDs; for this tooltip we threw in bonus information by showing you the Status of each task including counts for each status grouping regardless of whether there is an icon showing in the header or not (and if there are more than one appdomain in your app, we show the appdomain ID next to the task ID)


Feedback Please
Start playing with Visual Studio 2010 and let me have it!

Parallel Stacks – another new VS2010 debugger window

Wed, May 20, 2009, 01:19 PM under ParallelComputing
This post was UPDATED for the VS2010 Beta 2 release

Assumed knowledge aka Background Reading
It is important to understand some of the existing Call Stack window features. Even if you don't care about this VS2010 feature, you can improve your debugging skills with any version of Visual Studio by reading that blog post.

Parallel Stacks debugger toolwindow
With applications increasingly having more than one thread and with parallelism gaining momentum, we need the ability to view (and navigate) more than 1 call stack from a single view. Previously I discussed the motivation behind this new window here, and I'll use the exact same code for the following screenshots. Here is the new Parallel Stacks window:

In the picture above you can see the call stacks of 3 threads in a single view. The way you read this picture is that you have one thread that went from Main to A to B. Two other threads started from the same external code and then went to A, but one of them continued to B and then to some external code, and the other continued to C and then some AnonymousMethod. This is also the active stack frame and this is the current thread.

Toolbar buttons from left to right
Threads/Tasks combobox: Switches the view between showing call stacks of threads to showing call stacks of Tasks (and vice versa). More on the Tasks view of the Parallel Stacks window in another post.

Show Only Flagged: Shows call stacks only for the threads that are flagged in the Threads window.

Toggle Method View: Switches between normal view and method view. Method view is the subject of a separate post.

Auto Scroll To Current Stack Frame: Auto-scrolls the diagram so the current stack frame is in view. Useful in large diagrams when changing the current stack frame via other windows or when hitting a new breakpoint.

Toggle Zoom Control: Shows or hides the zoom control. Note that zooming is always available via Ctrl+mousewheel.

Context Menu Items in random order
The last 5 menuitems are borrowed directly from the Call Stack window and introduce no new behaviors: Go To Source Code, Go To Disassembly, Show External Code, Hexadecimal Display, Symbol Load Information and Symbol Settings.

Go To Task (Thread): This performs the same function as the combobox on the toolbar does, but additionally keeps the same stack frame highlighted. It will be discussed in a separate post.

Switch To Frame: Same as menuitem on Call Stack window. Additionally, with Parallel Stacks, multiple frames may correspond to a method context so the menuitem has submenus, each representing a specific stack frame. If one of the stack frames is on the current thread (so by definition you are clicking on a node with a blue highlight around it) then that stack frame has a checkmark in front of it. For example, right clicking on Program.A and expanding the first menuitem results in this screenshot:


Annotations and Elements Listed
Call Stack Segment or Node: Each "box" contains a series of method contexts for one or more threads. If the node has no arrow lines connected to it, then it represents the entire call path for the thread(s), otherwise you need to follow the arrows to piece together the entire call path of a thread.

Blue Highlight: The blue highlight indicates the call path to which the current thread belongs to.

Arrow lines: Arrow lines connect nodes to make up the entire call path for the thread(s).

Tooltip on Node Header: The tooltip on each node shows the ID(s) and name(s) of the thread(s) relevant to the node.


Method Context: Represents one or more stack frames in the same method.

Tooltip on method context: The tooltip on each method context shows the full details of all the stack frames it represents. If one of the stack frames is also on the current thread, it is shown in bold font.


Yellow Arrow Icon: A yellow arrow in front of a method context indicates that the active stack frame of the current thread is in that method context. As you'd expect, this icon would appear only at the last frame in a node that also has the blue highlight around it.

Cloth Threads Icon: A cloth threads icon in front of a method context indicates that the active stack frame of a non-current thread is in that method context. As you'd expect, this icon would appear only at the last frame in a node and there would be no blue highlight.

Green Arrow Icon: A green arrow in front of a method context indicates that the current stack frame is in that method context. That method context is also in bold font, and as you'd expect is in a node with a blue highlight. If the method context appears in other places/nodes on the diagram, it is bolded there too. E.g., if in the context menu shown above, we clicked on menuitem '4284: Program.A("hi") Line 19' we would be switching thread and current frame on that thread with a single action, resulting in the picture looking like this:


Navigation Aids
Bird's Eye View: When there are scrollbars present, the space between the scrollbars reveals a button that when pressed shows a thumbnail view of the picture which you can use to quickly scroll around it.

Zoom Control: The zoom control lets you zoom in and out, zoom to fit and zoom to 100%.

Panning: Pressing the mouse button on any white space and dragging, will scroll the diagram.

Call to Action
The call to action is identical to the Call to Action of my post on Parallel Tasks. Read it and come back here to comment ;-)

VS2010 fix for "not all anonymous methods are the same"

Tue, May 19, 2009, 12:56 PM under dotNET
Last September (wow, time flies!) I blogged about a VS2008 issue described as: Not all AnonymousMethods are the same. My team fixed this, so let's revisit the equivalent code from that post, this time in VS2010. The screenshot tells the story:

Notice that anonymous methods now have a suffix? This tells you immediately that the 2 threads are not at the same method. The information becomes even clearer with a new debugging window we are introducing in VS2010 that I will describe in my next post: Parallel Stacks.

Tasks documentation

Tue, May 19, 2009, 08:11 AM under ParallelComputing
Interested in the System.Threading.Tasks namespace? Read here the official MSDN documentation.

Parallel Tasks – new Visual Studio 2010 debugger window

Fri, May 15, 2009, 02:55 AM under ParallelComputing
This post was UPDATED for the VS2010 Beta 2 release

Assumed knowledge aka Background Reading
.NET 4 introduces a new class that lives in mscorlib that I have blogged about before: System.Threading.Tasks.Task, which as you'll recall is also what Parallel.For depends on. Collectively, all those new classes is what we refer to as Task Parallel Library and the team that owns it has blogged what is new for TPL in Beta1. Another .NET 4 feature I blogged about before also depends on Tasks for its implementation: Parallel LINQ. The same team owns that and there is a blog post of what is new for PLINQ in Beta1.

If you are a C++ developer, then you'll be happy to know that the task concept also exists in C++ version 10 that ships with VS2010. In addition to the dedicated native concurrency blog I just linked to, there is a ch9 video on the topic.

Parallel Tasks debugger toolwindow
To support the new task-based programming model introduced with Visual Studio 2010 for both managed and native developers, we are introducing a new debugger window: Parallel Tasks. You can open it after you hit a breakpoint, via the same location where all debugger windows live.


Sorting, Reordering, Hiding/Showing columns
Columns are re-orderable (by dragging them left/right) and sortable (by clicking on them) as indicated by the little triangle, which also shows the sort direction. You can also hide or show columns by right clicking on any column and then (un)checking the column menuitem of interest


Grouping on a column
Via the context menu shown above you can group on your column of choice. What is cool about grouping is that it allows you to flag an entire group with one click (more on flagging later), it allows you to collapse the group (preserved between debugging steps) and it shows a count of the items in the group (even when it is collapsed).


Description of the 9 Columns
- Flag Column: Each item can be in a flagged or non-flagged state (the default). You can toggle the state of a row by clicking on the corresponding cell. You would do this to make it easier to keep an eye on an item of interest between debugging steps (e.g. breakpoints, F11) or to flag multiple items and then sort on the column to bring them all to the top. Flagging is not persisted between debugging sessions. Another use of flagging is to filter the task call stacks shown in the new Parallel Stacks window, but that is a topic of another blog post.

- Icon Column: This column is blank by default except for one Task which will have a yellow arrow in this cell. The yellow arrow indicates which one is the current task. The current task is one which is executing on the current thread and you can switch current task just like switching current thread. The task which is current when you first break under the debugger is known as the "breaking task" and is indicated by a white hollow arrow icon (only visible after you switch task, of course). Another icon that can be displayed in this column is the "pause" icon to indicate a frozen thread (more on freezing further down).

- Id: Each Task has a unique Id which can be retrieved programmatically by calling the Id property (for C++ tasks, this will be the memory address). This is useful so you can map the task you are seeing in the window with diagnostic output you may send to some stream; it is also useful for cross-referencing tasks between the Parallel Tasks and the Parallel Stacks windows (which I'll describe in another post).

- Status: The 4 potential values here are Running, Scheduled, Waiting and Waiting-Deadlocked. "Running" are the tasks that are executing code at the moment your app breaks in the debugger (they are at top of stack of a running thread); "Scheduled" are the ones that are sitting in some queue but have not been executed by a thread yet; "Waiting" are the ones that have run, but are now blocked on something, e.g. a Monitor, a critical section; "Waiting-Deadlocked" are the ones that are "Waiting" and additionally we have detected a wait chain with other tasks in the list. For the 2 Waiting states, hovering over the cell displays a tooltip which may have more information, like in the following screenshot.


- Location: The Location column displays the method that the task is currently in (i.e. the top most user frame of the task's call stack). Hovering over the cell displays in a stacktip the entire call stack for the task (not the entire call stack for the thread!) and from the stacktip you can even switch the current stack frame by double clicking on your chosen one. Naturally, Scheduled tasks do not have a value in this column.


- Task: The entry point method that was passed to the task when it was constructed. If there was a state argument explicitly passed to the task, the value of that is also shown.

- Thread Assignment: The ID and name of the thread that the task is executing on. Remember, a task can only execute on a single thread, but a thread can be executing multiple tasks. Naturally, Scheduled tasks do not have a value in this column.

- Parent: The Id of the task that is the parent of this task (if there is one showing in the list). This is not applicable for native scenarios where the concept of parent and child tasks is not a first class citizen in the programming model.

- AppDomain: This column shows the AppDomain ID of the AppDomain in which the task belongs to (assuming you created more than one AppDomain). This is not applicable for native scenarios.

- Task Group: The address of the task_group that scheduled the task. This is not applicable for managed scenarios.

Parent Child View
When the value of any cell in the Parent column is not blank, we know we have parent child relationship(s) in our view. In that case, we can visualize this relationship slightly better by switching to "Parent Child View" via the column context menu (shown in image further above). This switches the first column to contain a treeview that allows collapsing the child nodes/tasks.


Task Context Menu
The ContextMenu described above is the one displayed when right clicking on a column; there is one that is displayed when right clicking on a (task) listviewitem.
- Copy: Copies the cells in view (tab delimited) to the clipboard.
- Select All: Or via Ctrl+A to select all tasks, in order to perform one of the other operations in bulk, e.g. copying.
- Hexadecimal Display: Global debugger setting that switches all debugger windows to hexadecimal display (or Decimal if unchecked).
- Switch To Task: Sets the selected task to be the current task (as discussed above) and hence get the yellow arrow icon. This action is also performed when double clicking on a Task listviewitem.
- Freeze Assigned Thread: The concept of freezing a thread existed before this Visual Studio release via the Threads window. The thread that is frozen does not continue execution when the debugger continues to the next step, until the user Thaws it (via the same menu). From the Parallel Tasks window, freezing affects the underlying thread and all tasks on it. I.e. this is still a thread concept rather than a task concept.
- Freeze All Threads But This: Freezes all threads in view, except the selected one.
- Flag: Same behaviour as clicking on the flag column, described further above.


Call to Action
When you get the Visual Studio 2010, let me know what you think about this new debugger window as you write your own task-based algorithms: do you like it or do you love it? ;-) More seriously, I am genuinely interested in your bug reports (so the talented developers on my team can fix them for future releases), what feature do you particularly like (so we make sure not to lose/break it) and what you'd like to see that is not there (so we can include it for the next release).

PDB Files

Wed, May 13, 2009, 03:39 PM under Links
I want to share this comprehensive blog article by John Robbins. No need to paraphrase the title, it perfectly describes the content already: PDB Files: What Every Developer Must Know.

Axum

Sat, May 9, 2009, 02:01 PM under ParallelComputing
My colleagues have released to DevLabs an incubation project: Axum (fka "Maestro").
"Axum aims to validate a safe and productive parallel programming model for .NET"

" Axum is a language that builds upon the architecture of the Web and principles of isolation, actors, and message-passing to increase application safety, responsiveness, scalability, and developer productivity.
Other advanced concepts we are exploring are data flow networks, asynchronous methods, and type annotations for taming side-effects."

After you visit the page and download the bits, head over to the dedicated Axum blog.