Community Pick: Many members of our community have endorsed this article.
Editor's Choice: This article has been selected by our editors as an exceptional contribution.

C/C++ Beginner's Debugging Guide using Visual Studio 2008 Express

phoffricSoftware Engineering and Matlab Analyst
CERTIFIED EXPERT
Software Engineering and Matlab Analyst
Published:
Updated:

Introduction

This article is the first in a series of articles about the C/C++ Visual Studio Express debugger.  It provides a quick start guide in using the debugger. Part 2 focuses on additional topics in breakpoints.  Lastly, Part 3 focuses on the Watch Pane, examining blocks of memory, and viewing memory at different levels of the Stack Frame.


Motivation To Begin Learning

NOTE: If you just want to get started quickly using the debugger, then SKIP this Motivational paragraph.

This article is intended to help students become quickly comfortable with the VS 2008 Express Debugger.  Students beginning in their study of C/C++ may shun the use of the very powerful symbolic debugger because of their belief that the learning curve is too prohibitive; after all, they have been successfully writing and debugging programs for the first couple of months using print statements.  But as the programs become a little longer and bugs creep in – and now, for some reason, it is harder to track down the problems.  The purpose of this article is to demonstrate that in a few minutes, a student can learn enough to significantly improve their productivity in completing assignments.

Some of the website tutorials on this topic are too comprehensive for a beginner who desires to quickly get started with this debugger.  Learning just what is described below can save many hours in a homework assignment and many weeks over all your computer classes.  For those who want to learn everything about the VS Symbolic debugger, see the MS Debugger Road-map.

TABLE OF CONTENTS

1. Building Program with Symbolic Debugging
1.1. Building in Debug Mode
1.2. Building a C Program
2. Program Navigation
2.1. Breakpoints
2.2. Starting the Program and Hitting Breakpoints
2.3. Stepping Through the Program
2.4. Setting the Next Statement to Execute
2.5. Caveat: Console Interaction with Debugger
3. Examining and Modifying Variable Values
3.1. Mouse Hovering Reveals Values and Structure
3.2. Quick Watch
3.3. Autos and Locals Tab
3.4. Modifying a Variable Value
4. Command Line Arguments
5. Stopping the debugger
6. Time to Practice

After becoming familiar with this short article, you may find interesting additional tips on the debugger breakpoint facility.  See this article for more on breakpoints.
       
Summary of Keyboard Commands Used in this Article
F5  – Start Debugging; or continue Debugging
F10 – Step over next line
F11 – Step into function or method
F9   – Set/Unset Breakpoint

<Ctrl+Shift+F5> –  Restart Program Debugging
<Ctrl+Shift+F10> –  Set position of next statement to execute

1. Building a Program with Symbolic Debugging

Symbolic debugging allows you to be able to view the values of symbols as you step through your program.  And it also allows you to set breakpoints where you would like your program to stop.  For this article, I have built a “General Empty” project.  This project reads in a very large list of scrabble words, and determines the largest set of anagrams in the list.

After becoming comfortable with the techniques described in this article, there are a few more tips that may be useful for more complicated projects that you can read about in  this follow-on article.
     

1.1. Building in Debug Mode

To be able to debug symbolically, you must build in Debug Mode rather than Release Mode, or the necessary symbols will not be available to the debugger.  The following figure shows how to set it in case you change the default Debug Mode setting.  See Figure 1 to see how to set the build to Debug Mode: A.1 debugMode.GIF
Figure 1 Debug Mode

The advantage of Release Mode is that it is usually more efficient since the compiler is able to better optimize the code. The advantage of Debug Mode is that you do not have to add print statements to debug your code and figure out what your program is doing.

1.2. Building a C Program

With the Visual Studio 2008 Express Symbolic Debugger, you can debug either C++ or C programs.  For C programs, be sure that your file extension is .c and not .cpp, or else the C++ rules will apply.  What works for you now as a C++ program may fail to compile when you hand in your assignment.

2. Program Navigation

This section describes how to understand the control flow of the program.  For example, you will be able to determine whether certain lines of code are being reached, and if not, help determine why not.

2.1. Breakpoints

After you get a program to compile and build (preferably with no warnings), you can set breakpoints.  A breakpoint is placed on a line of code where you would like the program to stop so that you can verify that it got where it should, and that the variables have the expected values when the breakpoint is reached.

To set a breakpoint, put the cursor on the line of interest, and hit F9.  Hitting F9 again will remove a breakpoint; or you may be able to just click on a vertical gray strip to the left of that line, and a red breakpoint circle symbol appears; and another click on the symbol removes it.  You can set many breakpoints if desired.  After setting a breakpoint (as shown in Figure 2), you will see a red breakpoint circle.A.2-Set-Breakpoint.GIF
Figure 2 Set Breakpoint

It is useful to set a breakpoint at the last return in the main function so that the program stops for your inspection before exiting.  By doing this, you do not need a getchar() statement at the end of the program to prevent the console from closing before you have a chance to review the output.

2.2. Starting the Program and Hitting Breakpoints

After setting breakpoints, hit Debug -> Start Debugging (or just F5) as shown in Figure 3: A.3-1-Start-Debugging-F5.GIF
Figure  3 Start Debugging F5

The program will run as usual with the windows console being displayed.  But when the program hits a breakpoint, it will stop.  You should see a program pointer (a yellow arrow within the red circle - see Figure 4) at the line where the program stopped.A.3-2-Hit-breakpoint-and-Hover.GIF
Figure  4 Hit breakpoint and Hover

The program hit line 47 (which happens to be in a function).  If you hover the mouse over the variable “word” in line 46, you will see what the program has just read into the string; in Figure 4, you see that the program just read into the string “aardvark” from a file.

2.3. Stepping Through the Program

Hitting F10 will execute the line of code pointed to by the program pointer.  F10 will step over a function (i.e., the entire function will be executed and will return uninterrupted unless there is also a breakpoint in that function).

Another way to start a program other than hitting F5 is to hit F10.  This results in the program pointer being set at the first executable line of code in your main function.  Hitting F10 successively allows you to walk through the program.

If the yellow arrow is pointing to a method or function, then hitting F11 will step into it.  Then you can go back to hitting F10 to walk through the method or function.  If you are in a method or function and wish to get back to the caller in one step, then you can hit the “Step Out” button as shown in Figure 5: A.5 Step-Out
Figure  5 Step Out

2.4. Setting the Next Statement to Execute

Suppose you stepped into a method to review it, and after it returns, you wish to do step into it again.  Rather than resuming (i.e., F5), or re-starting the program over again (<Ctrl+Shift+F5>, but which may be inconvenient in a complex program), you can reset the Next Statement To Execute to the line containing the method.  Then, you can hit F11 to step back into the function.  To do this, place the cursor on the line of code where you want the execution to resume from, and then either enter the default keyboard shortcut, <Ctrl+Shift+F10>, or right-click and select "Set Next Statement".  However, this is a useful enough command to add it to your debug toolbar.

2.5. Caveat: Console Interaction with Debugger

Suppose you have a program that accepts user input from the VS Console, and after entering the input, you observe that you reached a breakpoint.  But then you try to hit F5 to continue the program, but there is no effect.  The reason is that the Windows focus is still on the VS Console; you have to give focus back to the debugger by clicking on the VS Debugger first. Now your F5 operation should work.

On this topic of focus, if it appears that hitting a toolbar command button has no effect, it may be that the first time you hit it, all that happened was to give Windows focus to the VS Debugger.  Now the window is ready to accept mouse or keyboard commands, so try hitting the button one more time.

3. Examining and Modifying Variable Values

There are several simple ways to inspect and modify data.  Some methods provide quick temporary views (e.g., Mouse Hover and Quick Watch). There are also panes that enable you to view local variables in methods or functions.

3.1. Mouse Hovering Reveals Values and Structure

As already shown in Figure 4, if you hover the mouse over a variable, you will get a small popup that shows its value.  In Figure 6 the mouse is hovered over the variable, “words”.  First you see that the value of “words” is “paleontologist”.  Then by hovering over the +sign, the data expands in more detail showing the chars 0 through 13 and their ASCII and decimal representations.  If you right-click on this expansion, a popup menu allows you to switch to a hexadecimal representation.A.7.1 Hover Mouse Expand
Figure 6 Hover Mouse Expand

You need not concern yourself with the names such as _Mysize and _Myres that you can see in the value expansion.  These names are internal to Visual Studio.  (But for those who are curious, it appears that _Mysize is the length of the string, and that _Myres is the number of bytes that is currently allocated to the string.)

3.2. Quick Watch

If you right-click on "words" in the source code, then you can select QuickWatch and then, in addition to what was shown above, you also see the data types.  This is especially useful when examining data structures or user defined class objects.  Figure 7 shows an example of the QuickWatch Dialog box.  As the name suggests, this is a temporary view of reviewing data of interest.  If you hit the Add Watch button, the information is transferred into a more permanent Watch Pane.A.7.2 QuickWatch
Figure  7 Quick Watch

3.3. Autos and Locals Tab

In the bottom left hand side of your screen, should be a number of tabs, including Autos and Locals.  These panes have three columns - variable Name, Value, and Type.

The Locals tab displays all the variables that are on the local stack of the function that you are in.  Figure 8 illustrates an example of a Locals pane: A.7.3 Local Variables
Figure 8 Local Variables
The Autos tab shows information about both local and global variables in the current line and previous line of code.  Note that the global variables do not appear in the Locals pane.  The Autos tab is especially convenient if you have many local variables and wish to quickly focus only upon variables related to recently executed instructions.

Hit the Autos tab when you hit a breakpoint.  You should now see a number of variable names and their values.  When debugging, take a few minutes to carefully look at the names, values, and their Data Types; and confirm that these values make sense to you.  Notice that when you step through a block of code one line at a time (using F10), the variables that appear may change; and when they do change, these values are displayed in red.  If no change, the value will remain black.  For data types that are composites of other types (such as strings, arrays, or classes) you will see a +sign preceding an object variable.  By hitting the +sign, you will expose the underlying structure within the object.

3.4. Modifying a Variable Value

In the Locals or Autos panes, you will see three fields - Name, Value, and Type.  If you double-click on a primitive numeric or char value, it should become editable.  You can then insert a valid value for that variable.  In general, if you can examine data by any of the methods described above, you can double-click on it and change the value.  If you try to change the variable “words”, which is a string, you have to expand it; and then you can change individual chars by inserting either a number or a literal char such as ‘x’.

4. Command Line Arguments

If your main program begins with
            int main( int argc, char **argv )
then there is a good chance that you need to set command line arguments so that argc and argv have set values. To set up your debugger with Command Arguments, bring up the Properties Page for your project (i.e., Right-click on the project, and select Properties). In the Property Pages Dialog Box, expand "Configuration Properties" and highlight "Debugging" (see Figure 9). Then, in the right pane, highlight Command Arguments, and enter the strings in the text field.Command Line Arguments
Figure 9  Command Line Arguments

5. Stopping the debugger

If you want to shut down a debugging session, you can do so from a paused state.  There is a small blue box in your (debugging) toolbar that you can hit to stop the debugger (see Figure 10).  It will cause your console output screen to close down.  If you are not stopped at a breakpoint, then it may be necessary to first hit the pause button (see Figure 11), which is just to the left of the Stop Debugging button.Stopping the Debugger
Figure 10 Stopping the Debugger
A.6-3 Pause
Figure 11 Pausing the Debugger

Caveat: Due to a bug in either VS and/or XP, sometimes the output debugger console window does not shut down properly.  In this case, I and others have found no way to remove it, and it may even prevent a normal power shutdown of the PC (then holding the PC power switch for 10 seconds shuts down the system).  The workaround is simple - minimize the console window, and live with it until you shut down.  It does not appear to have any deleterious effects other than forcing a manual shutdown, and inability to log out of your session.  There is hope, however.  MS has issued this information indicating that there may be a solution someday.

6. Time to Practice

The saying that practice makes perfect is a cliche that never loses its importance or meaning. I hope that you are encouraged to take out the debugger and start using it immediately. I hope that the above steps will help speed up your understanding and debugging of your programs.

After becoming familiar with this short article, you may find interesting additional tips on the debugger breakpoint facility.  More information on breakpoints can be found in  Part 2 of this Visual Studio 2008 Debugger article series.
9
9,105 Views
phoffricSoftware Engineering and Matlab Analyst
CERTIFIED EXPERT
Software Engineering and Matlab Analyst

Comments (2)

Commented:
my "yes" is here.

You didn't mention such things as $err, $tib, $clk in the watch window. I think, it's ok, because the article name is "Getting Started...".

Great article!

John Robbins. Debugging Applications for Microsoft .NET and Microsoft Windows
http://www.amazon.com/dp/0735615365/?tag=sollc-intl-20
 
Microsoft Visual C++ Tips and Tricks
http://www.highprogrammer.com/alan/windev/visualstudio.html

An introduction to debugging in MSVC++ using Pseudoregisters
http://www.codeproject.com/KB/debug/pseudoregister.aspx
phoffricSoftware Engineering and Matlab Analyst
CERTIFIED EXPERT
Distinguished Expert 2022

Author

Commented:
Rick,
I was in the process of moving sections 2-xxx to separate follow-on articles (to keep the first article extremely simple - as we had discussed) when it was accepted. I can start that process today.
    Paul

Have a question about something in this article? You can receive help directly from the article author. Sign up for a free trial to get started.