Tutorial: Learn to debug using Visual Studio
This topic introduces the features of the Visual Studio debugger in a step-by-step walkthrough. If you want a higher-level view of the debugger features, see Debugger Feature Tour. When you debug your app, it usually means that you are running your application with the debugger attached. When you do this, the debugger provides many ways to see what your code is doing while it runs. You can step through your code and look at the values stored in variables, you can set watches on variables to see when values change, you can examine the execution path of your code, et al. If this is the first time that you've tried to debug code, you may want to read Debugging for absolute beginners before going through this topic.
You can either read along to see the features of the debugger or you can download the complete sample used in the feature tour and follow the steps yourself. To download the sample and follow along, go to Photo Viewer Demo.
|Watch a video on debugging that shows similar steps.|
In this tutorial, you will:
- Start the debugger and hit breakpoints.
- Learn commands to step through code in the debugger
- Inspect variables in data tips and debugger windows
- Examine the call stack
- Use the Exception Helper
You must have Visual Studio 2017 installed and the .NET desktop development workload.
If you haven't already installed Visual Studio, go to the Visual Studio downloads page to install it for free.
If you need to install the workload but already have Visual Studio, click the Open Visual Studio Installer link in the left pane of the New Project dialog box (select File > New > Project). The Visual Studio Installer launches. Choose the .NET desktop development workload, then choose Modify.
Start the debugger!
To follow along these steps in Visual Studio, download the sample on this page.
You need to install Visual Studio with the .NET Desktop Development workload to run the app we're using in the demo.
Unzip the project.
Open Visual Studio and select the File > Open menu command, then choose Project/Solution, and then open the folder where you downloaded the project.
Open the WPF Photo Viewer Demo > C# folder, choose the photoapp.sln file, and select Open.
The project opens in Visual Studio. Solution Explorer in the right pane shows you all the project files.
Press F5 (Debug > Start Debugging) or the Start Debugging button in the Debug Toolbar.
F5 starts the app with the debugger attached to the app process, but right now we haven't added any breakpoints or done anything special to examine the code. So the app just loads and you see the photo images.
In this tour, we'll take a closer look at this app using the debugger and get a look at the debugger features.
Stop the debugger by pressing the red stop button.
Set a breakpoint and start the debugger
To debug, you need to start your app with the debugger attached to the app process.
MainWindowconstructor of MainWindow.xaml.cs, set a breakpoint by clicking the left margin of the first line of code.
Breakpoints are the most basic and essential feature of reliable debugging. A breakpoint indicates where Visual Studio should suspend your running code so you can take a look at the values of variables, or the behavior of memory, or whether or not a branch of code is getting run.
Press F5 or the Start Debugging button, the app starts, and the debugger runs to the line of code where you set the breakpoint.
The yellow arrow represents the statement on which the debugger paused, which also suspends app execution at the same point (this statement has not yet executed).
F5 continues running the app to the next breakpoint. (If the app is not yet running, F5 starts the debugger and stops at the first breakpoint.)
Breakpoints are a useful feature when you know the line of code or the section of code that you want to examine in detail.
(Optional) Restart your app quickly
Click the Restart button in the Debug Toolbar (Ctrl + Shift + F5).
When you press Restart, it saves time versus stopping the app and restarting the debugger. The debugger pauses at the first breakpoint that is hit by executing code.
The debugger stops again at the breakpoint you set, in the
Navigate code in the debugger using step commands
Mostly, we use the keyboard shortcuts here, because it's a good way to get fast at executing your app in the debugger (equivalent commands such as menu commands are shown in parentheses).
Press F11 (Debug > Step Into) twice to advance the execution of the app to the
F11 is the Step Into command and advances the app execution one statement at a time. F11 is a good way to examine the execution flow in the most detail. (To move faster through code, we show you some other options also.) By default, the debugger skips over non-user code (if you want more details, see Just My Code).
In managed code, you will see a dialog box asking if you want to be notified when you automatically step over properties and operators (default behavior). If you want to change the setting later, disable Step over properties and operators setting in the Tools > Options menu under Debugging.
Press F10 (Debug > Step Over) a few times until the debugger stops on the first line of code in the
F10 advances the debugger without stepping into functions or methods in your app code (the code still executes). By pressing F10 on the
InitializeComponentmethod call (instead of F11), we skipped over the implementation code for
InitializeComponent(which maybe we're not interested in right now).
Step into a property
With the debugger paused on this line of code:
mainWindow.Photos.Path = Environment.CurrentDirectory + "\\images";
Right-click on the line of code and choose Step Into Specific, then SDKSamples.ImageSample.PhotoCollection.Path.set
As mentioned earlier, by default the debugger skips over managed properties and fields, but the Step Into Specific command allows you to override this behavior. For now, we want to look what happens when the
Path.setproperty setter runs. Step Into Specific gets us to the
Updatemethod in this code looks like it could be interesting, so lets use the debugger to examine that code up close.
Hover over the
Updatemethod until the green Run to Click button appears on the left.
The Run to Click button is new in Visual Studio 2017. If you don't see the green arrow button, use F11 in this example instead to advance the debugger.
Click the Run to Click button .
Using this button is similar to setting a temporary breakpoint. Run to Click is handy for getting around quickly within a visible region of app code (you can click in any open file).
The debugger advances to the
Press F11 to step into the
Here, we find some more code that looks interesting; the app is getting all .jpg files residing in a particular directory, and then creating a Photo object for each file. This code gives us a good opportunity to start inspecting your app state (variables) with the debugger. We will do that in the next sections of this tutorial.
Features that allow you to inspect variables are one of the most useful features of the debugger, and there are different ways to do it. Often, when you try to debug an issue, you are attempting to find out whether variables are storing the values that you expect them to have at a particular time.
Examine the call stack
While paused in the
Update method, click the Call Stack window, which is by default open in the lower right pane.
The Call Stack window shows the order in which methods and functions are getting called. The top line shows the current function (the
Update method in the tour app). The second line shows that
Update was called from the
Path.set property, and so on.
The Call Stack window is similar to the Debug perspective in some IDEs like Eclipse.
The call stack is a good way to examine and understand the execution flow of an app.
You can double-click a line of code to go look at that source code and that also changes the current scope being inspected by the debugger. This action does not advance the debugger.
You can also use right-click menus from the Call Stack window to do other things. For example, you can insert breakpoints into specified functions, advance the debugger using Run to Cursor, and go examine source code. For more information, see How to: Examine the Call Stack.
Let's say that you are done examining the
Update method in Data.cs, and you want to get out of the function but stay in the debugger. You can do this using the Step Out command.
Press Shift + F11 (or Debug > Step Out).
This command resumes app execution (and advances the debugger) until the current function returns.
You should be back in the
Updatemethod call in Data.cs.
Press Shift + F11 again, and the debugger goes up the call stack back to the
Run to cursor
Choose the Stop Debugging red button or Shift + F5.
Updatemethod in Data.cs, right-click the
Addmethod call and choose Run to Cursor. This command starts debugging and sets a temporary breakpoint on the current line of code.
You should be paused on the breakpoint in
MainWindow(since that is the first breakpoint you set).
Press F5 to advance to the
Addmethod where you selected Run to Cursor.
This command is useful when you are editing code and want to quickly set a temporary breakpoint and start the debugger.
Change the execution flow
With the debugger paused on the
Addmethod call, use the mouse to grab the yellow arrow (the execution pointer) on the left and move the yellow arrow up one line to the
By changing the execution flow, you can do things like test different code execution paths or rerun code without restarting the debugger.
Now, press F5.
You can see the images added to the app window. Because you are rerunning code in the
foreachloop, some of the images have been added twice!
Often you need to be careful with this feature, and you see a warning in the tooltip. You may see other warnings, too. Moving the pointer cannot revert your application to an earlier app state.
Inspect variables with data tips
Open Data.cs in the Photo Viewer Demo app, right-click the
private void Updatefunction declaration and choose Run to Cursor (stop the app first if it is already running).
This will pause the app with the debugger attached. This allows us to examine its state.
Hover over the
Addmethod call and click the Run to Click button .
Now, hover over the File object (
f) and you see its default property value, the file name market 031.jpg.
Expand the object to see all its properties, such as the
Often, when debugging, you want a quick way to check property values on objects, and the data tips are a good way to do it.
In most supported languages, you can edit code in the middle of a debugger session if you find something you want to change. For more info, see Edit and Continue. To use that feature in this app, however, we would first need to update the app's version of the .NET Framework.
Inspect variables with the Autos and Locals windows
Look at the Autos window at the bottom of the code editor.
In the Autos window, you see variables and their current value. The Autos window shows all variables used on the current line or the preceding line (In C++, the window shows variables in the preceding three lines of code. Check documentation for language-specific behavior).
Next, look at the Locals window.
The Locals window shows you the variables that are in the current scope.
thisobject and the File object (
f) are in the current scope. For more info, see Inspect Variables in the Autos and Locals Windows.
Set a watch
In the main code editor window, right-click the File object (
f) and choose Add Watch.
You can use a Watch window to specify a variable (or an expression) that you want to keep an eye on.
Now, you have a watch set on the
Fileobject, and you can see its value change as you move through the debugger. Unlike the other variable windows, the Watch window always shows the variables that you are watching (they're grayed out when out of scope).
Addmethod, click the green button again (or press F11 a few times) to advance through the
You might also see the first picture get added to the main window of the running sample app, but this happens on a different app thread, so images may not be visible yet.
For more info, see Set a Watch using the Watch and QuickWatch Windows
Examine an exception
In the running app window, delete the text in the Path input box and select the Change button.
The app throws an exception, and the debugger takes you to the line of code that threw the exception.
Here, the Exception Helper shows you a
System.ArgumentExceptionand an error message that says that the path is not a legal form. So, we know the error occurred on a method or function argument.
In this example, the
DirectoryInfocall gave the error on the empty string stored in the
valuevariable. (Hover over
valueto see the empty string.)
The Exception Helper is a great feature that can help you debug errors. You can also do things like view error details and add a watch from the Exception Helper. Or, if needed, you can change conditions for throwing the particular exception.
The Exception Helper replaces the Exception Assistant in Visual Studio 2017.
Expand the Exception Settings node to see more options on how to handle this exception type, but you don't need to change anything for this tour!
Press F5 to continue the app.
To learn more about the features of the debugger, see Debugger Tips and Tricks.
In this tutorial, you've learned how to start the debugger, step through code, and inspect variables. You may want to get a high-level look at debugger features along with links to more information.