The Output window is a veteran in the war against bugs and has been part of Visual Studio since its very first release. It is comprised of a collection of text panes that communicate information to the user:
The Output window can be extended by adding to its collection of text panes programmatically, but out of the box with a typical project most users will see the following:
- Build: Contains messages about builds and their status (e.g. compilation warnings)
- Build Order: Same as “Build”, only the output is logically ordered for readability (vs chronological order)
- Debug: Contains messages from the debugger plus any text the application output during execution.
On this post we will focus on the Debug pane and its capabilities.
The Debug text pane of the Output window
One of the most popular and commonly used text panes of the Output window is Debug. It contains the following type of messages:
- Exception Messages: Notification of first-chance exceptions (e.g. “A first chance exception of type 'System.ArgumentException' occurred in MyAssembly.dll”). When Just My Code is enabled you only see these for exceptions that occur in user code.
- Step Filtering Messages: Notifications of when the debugger’s Just My Code settings result in skipping non-user code while stepping (e.g. “Step into: Stepping over non-user code 'System.Data.DataRow.this[int].get'”).
- Module Load/Unload Messages: Notification of modules (basically, .NET assemblies) being loaded or unloaded from the app domain, including notification if symbols were loaded along with them (e.g. “'ConsoleApp1.vshost.exe' (CLR v4.0.30319: ConsoleApp1.vshost.exe): Loaded 'C:\...\blah.dll'. Symbols loaded.”)
- Process Exit Messages: Notification of processes terminating (e.g. “The program '[11152] ConsoleApp1.vshost.exe' has exited with code 0 (0x0).”)
- Thread Exit Messages: Notification of thread terminating (e.g. “The thread 0x2c8 has exited with code 259 (0x103).”)
- Program Output: Messages that the application is sending programmatically through APIs such as Debug.WriteLine. for managed code, OutputDebugString for native code and Debug.writeln for JavaScript.
- Runtime trace information: Depending on your settings (i.e. Debug > Options and Settings > Output Window > WPF Trace Settings) WPF and XAML will output trace information (e.g. binding errors).
You can filter in or out each category of messages using the Debug pane’s right click context menu. Unfortunately messages that were filtered out in the past will not appear after the filter has been changed, so choose your filter settings wisely by anticipating your needs:
The same filter is also available through Debug > Tools and Settings > Output Window:
Tip #1: If you are seeing these type of messages in your Immediate window instead of your Output window, then you probably have the option “Redirect all Output Window text to the Immediate Window” checked under Debug > Tools and Settings > General.
Tip #2: You can always select text and copy & paste from any text pane of the Output window, but one handy feature that is somewhat hard to discover is the ability to save the entire contents to a file. If you set the focus to the Output window and you either use the Visual Studio menu item File > Save Selected Items or you use the shortcut CTRL + S you will be asked to specify the file within which to store the contents.
How the Output window can help with tough debugging problems
The Output window may look like a primitive debugging tool at first, especially compared to some of the other powerful debugging features of Visual Studio, but it can help you in some tough situations.
Hunting for a swallowed exception that is thrown often
Visual Studio offers you various features and options around exceptions, such as the Exception Assistant and the ability to break on first-chance exceptions. However, there are situations in which these features are a bigger hammer than what you need to pinpoint the root cause of the issue you are investigating.
A common scenario is looking for a swallowed exception that is thrown and caught so often that breaking on first-chance exceptions becomes too tedious. You can work around this by using the Debug pane of the Output window to view the exception messages without breaking for every one of them.
The Output window will contain a first chance exception message for every exception thrown (remember that when JMC is enabled these are limited to exceptions in user code only). That may not be enough, because you will not know which one is the one you are interested in. You can build context around and narrow down to the interesting one by generating program output messages (in .NET using Debug.WriteLine() or Trace.WriteLine()) and by enabling other interesting messages such as Thread Exit. For example:
> A first chance exception of type 'System.NullReferenceException' occurred in MyApp.exe
…
> A first chance exception of type 'System. NullReferenceException' occurred in MyApp.exe
…
> Starting comparison on a new thread
> Step 1: Calculating new hash
> Step 2: Retrieving historical hash
> Step 3: Comparing hashes
> A first chance exception of type 'System. NullReferenceException' occurred in MyApp.exe
> The thread 0x1ee8 has exited with code 259 (0x103).
…
> A first chance exception of type 'System. NullReferenceException' occurred in MyApp.exe
…
Looking at the above you can tell there are many first chance exceptions messages of type ‘System.NullReferenceException’, which is why I’d have to dismiss too many dialogs for the false positives if I had chosen to break on first-chance exceptions. However, using my program output messages I can tell that there is an issue with “Step 3: Comparing hashes” which results in an exception and the thread existing early before the comparison has been completed. To play around with this kind of Output, you can download my contrived Visual Studio project that resulted in the Output above (it’s a C# console application).
Debugging data binding and other XAML related issues
If you are building a WPF, Windows Store or Windows Phone application you are probably using data binding in your UI. Although data binding is a powerful and flexible mechanism using which you can build complex data-driven UIs very easily, it is still possible to get it wrong sometimes. The debugging experience when data binding fails is less than ideal. The failure is typically silent, without any exceptions being thrown and you only know because the UI hasn’t rendered as you expected or perhaps the data was not updated correctly in the database.
The Debug pane of the Output window can give you tracing information on binding failures, for example:
System.Windows.Data Error: 35 : BindingExpression path error: ‘Picture’ property not found on ‘object’ ”Car’ (HashCode=49535530)’. BindingExpression:Path=Picture; DataItem=’Car’ (HashCode=49535530); target element is ‘Image’ (Name=”); target property is ‘Source’ (type ‘ImageSource’)
The above is telling me that I’m trying to bind the property “Picture” of the object “Car”, but the property does not exist. Much better than simply not having the image show up.
Specifically for WPF you can additionally get tracing information for other XAML events such as Animation and Routed Events. You can change the level of tracing you get through Debug > Options and Settings > Output Window (or by changing the config, or programmatically):
Figuring out why your breakpoint is not getting hit
If the debugger can’t get access to symbols your breakpoint will not be hit:
Figuring out why symbols are not being loaded can be tricky. Symbols are loaded at the same time that the module is being loaded into the process. So it’s possible that the entire module you are setting a breakpoint in is not being loaded. Sometimes symbols simply do not exist because the module is being loaded from a location that doesn’t also contain the symbols.
If you use the Output window and look for the Module Load messages (e.g. “'ConsoleApp1.vshost.exe' (CLR v4.0.30319: ConsoleApp1.vshost.exe): Loaded 'C:\...\blah.dll'. Symbols loaded.”), you will be able to tell:
- Which modules are being loaded or unloaded and in what order
- Whether symbols were successfully loaded along with the module
- What location each module is being loaded from, so you can double check the symbols are in the same path
Note that you can get the same Module load information plus a lot more from the Modules window. However, the Modules window only offers a snapshot in time and not streaming information that can be interleaved with other messages in the Output window and hence help you build context. Also while the Modules window will show you the loaded modules, it will not offer insight about modules that have been unloaded.
To find out more about symbols and how Visual Studio uses them, check out our blog post on Understanding symbol files and Visual Studio’s symbol settings.
How is the Output window a hero to you?
Do you have other uses for the Output window that were not covered in this post? We would love to know how this old, trusty tool is helping you be more efficient or solve issues, so let us know. Have you extended the Output window to get more diagnostic information during your debugging? Now is the time for a shameless plug.
We are always looking for feedback and comments for our features. Please use Send-A-Smile, leave a comment or visit the MSDN Diagnostics forums.