Lab 2: Debugging C with VS Code
In this lab, you’ll practice using VS Code’s C debugger.
The images in this lab are from Windows. The Mac and Linux versions of VS Code look similar to this, but not identical, so you should adapt accordingly.
What’s a debugger?
A debugger is a tool designed to help you debug your programs. Debuggers tend to have a lot of sophisticated features, but the core of what you need to know is this: a debugger allows you to run your program one line at a time, enabling you to examine your variables along the way. If you can watch your variables evolve one slow line of code at a time, you can usually track down your errors.
Setting breakpoints and inspecting variables
To get started, launch VS Code and connect to mantis
. Go back and look at Lab 1 again if this process isn’t yet ingrained in your memory.
Now, let’s get started debugging:
-
Install the
C/C++ Extension Pack
: Select theView
->Extensions
menu, search for theC/C++ Extension Pack
from Microsoft, and install it. -
Get a program to debug: Copy the
debug_this.c
sample to your working directory onmantis
. You can do this usingFile
->New Text File
and then copy-pasting the contents. (Alternatively, you can use yourmantis
terminal and a variant of thewget
command described in theStarting C assignment
to grabdebug_this.c
—it’s good to be comfortable using either approach.) -
Read the code: Take a look through
debug_this.c
and see if you can spot the bug. Either way, run it and observe the bug. (Yes, it’s a simple one to fix, but let’s leave it be for now.) -
Set a breakpoint: Once you have a copy of
debug_this.c
open in VS Code, scroll down to the functioniterative_triangular_number
. At the line with thefor
loop, hover your mouse to the left of the line number. You will see the ghost of a red dot. Click it to make that red dot solid.
When you run the program in debugging mode, the program will stop just before executing the line of code at your breakpoint.
- Start debugging: You can do this either from the
Run
menu or from the play-button-with-a-bug in the upper-right corner of VS Code.
Your program will stop when it first gets to your breakpoint.
- Look around for a minute: In the code, the line at your breakpoint is highlighted. This line has not yet executed.
There’s a debugging toolbar at the top with different debugging buttons, including a continue button to let your program continue from where it left off and a stop button for stopping the program. Hover over the buttons to see their names (and keyboard shortcuts).
There is also the terminal/console display at the bottom of the window, showing that the program has already produced some output,but is stopped halfway.
Most important of all, in the upper-left corner of the VS Code window, there is the Variables panel, showing you the current values of the variablesk
andtotal
, as well as the parametern
. Note thatk
hasn’t been initialized yet, so it may have some (seemingly) random value.
Finally, in the bottom left, there’s the Call Stack. What do you think this is?
-
Step through your code: When the program stopped at your breakpoint, you were in the middle of
iterative_triangular_number(1)
(how can you tell?). You can now step through your program one line at a time.-
Click the
Step Over
button in the debugging toolbar. -
Look at the Variables panel. Did the variable values change the way you expected them?
-
Repeat until the program returns to
main
. Go slowly and pay attention to what changes after each click of theStep Over
button. -
Keep going until you’re at the line in
main
wheniterative_triangular_number(2)
is about to be called. Now, instead of clickingStep Over
, click theStep Into
button. -
Keep doing this as long as you want (or until you observe the bug).
-
It is extremely valuable to be able to step through your code slowly to see whether it’s doing what you expect it to do. Get in the habit of doing this when you have a bug, but also even when you think your code is working. You can find a lot of subtle bugs this way.
-
Done debugging: You can stop by clicking the
Stop
button. You can get theFile Explorer
pane back via theView
->Explorer
menu or clicking the appropriate button on the far left. -
Fix the bug: Now that you’ve found the bug, you can fix it! Do so, then click the red dot by line 45 to remove your breakpoint, rerun your program, and observe that it is fixed.
Debugging with command-line arguments
Get a copy of character_counter.c
into your mantis
working directory. Recall that this program requires a command-line argument. This section walks you through providing that argument to the debugger.
-
Open
character_counter.c
in VS Code. -
Open the “configuration” file for your debugging session. Note that if you don’t have one, you’ll have to select
Add Configuration...
.
- Here is what my config file looks like. Yours will likely be similar, or you can copy down these lines:
- Create a small text file for
character_counter.c
to work on. Here is mine:
- Edit (and save) the config file to enter your command-line argument.
- Open
character_counter.c
and run it in the debugger. Does it work? (Note: I’ve had differing luck with the menu option, the far-left play-plus-bug button, and the top-right play-plus-bug button, so if one isn’t working, try another.)
A few more things to try
Here are a few more things to try out and ponder. It will be really helpful to you later to get comfortable using a debugger now, so I encourage you try them now, and revisit them if you’re having any issues later! You can also ask about these in office hours if there is anything I can help clear up.
-
In
debug_this.c
:-
Comment out everything in
main
except thereturn
statement. -
Add a call to
recursive_triangular_number(10)
and aprint
statement to print out its result. -
Put a breakpoint somewhere in
recursive_triangular_number
. -
Run the debugger.
-
When you hit the breakpoint, take a look at the Variables panel; is it showing what you expect? Also, look at the Call Stack panel; is it showing what you expect?
-
Click the
Continue
button. You should land at your breakpoint again. How have the Variables and Call Stack panels changed? Repeat this a couple of times. -
Now, you should have quite a few function calls showing in the Call Stack. Click on each of them, and when you do, look at the Variables panel. What changes as you click on each function call? Explore, experiment, etc.
-
How would you explain the Call Stack to a CS 111 student?
-
-
What is the difference between the
Step Over
andStep Into
buttons? Test this. Also, what happens if you try toStep Into
a C library function likeprintf
? -
What if your program requires more command-line arguments? What syntax do you use in the
launch.json
(config) file? -
Declare an array in
main
or some other function and break somewhere in that function. What does the array look like in the Variables panel? -
Put a breakpoint in
character_counter.c
’smain
just beforeget_character_count
gets called. When your program hits that breakpoint, take a look at theinput_file_name
variable in the Variables panel. Make sure your Variables panel is wide enough that you can see both the numerical/address value ofinput_file_name
as well as the string that it points to.
That’s it!
There is a lot more to learn about using a debugger, but this should give you a good start. Keep practicing, and as always, ask questions you may have!