It’s hard to write correct programs. It’s especially hard to write correct programs on the first (or second, or third) try. You’ve probably figured that out by now. You’ve probably even seen your instructor make some mistakes while trying to write programs “live” during class. And, as you may have discovered, there are a lot of ways in which a program can be “wrong”. The programmer may have designed an incorrect algorithm and not realize it. The programmer may have incorrectly translated the algorithm into Scheme. The programmer may misunderstand how a particular Scheme operation works. The programmer may have missed some edge or corner cases. The list goes on and on.
Just as there are a wide variety of things that can go wrong with your program, there are also a wide variety of approaches that one takes to fix programs. You’ve seen one important technique: “Talking through” your code with another person, often with an example in mind, helps you ensure that your algorithm is correct, that you’ve correctly translated it into Scheme, and that you’ve understood the built-in and library procedures you are using. You may have also realized that it’s possible to debug a more complex piece of code by breaking it into smaller pieces and making sure that each piece works correctly.
You should also have found that DrRacket can help you identify syntax errors or parenthesization mistakes, such as by telling you when it doesn’t know a name you’ve used or by showing you through indentation how things are nested.
Of course, to fix code you also need to know when there are problems with code. Our early exploration of testing suggests one approach: You design a variety of tests and think about edge and corner cases, and you do so before you start to write the code. Once again, “talking through” things can help.
But what do you do once you have good tests and you’ve manually stepped
through the code to make sure that it seems to do what you think it
should? At that point, some programmers put a lot of output statements
display) in their program. However, good programmers more
often turn to a debugger, a program that lets you step through the
program and check the state of the system as you go. In this reading,
we explore DrRacket’s debugger.
As you explore different programming languages and program development environments, you will find that most debuggers have a few core aspects.
Some debuggers have a graphical user interface (GUI). Others are based on text that you type. Different users and different situations call for different kinds of debugging.
Now that you know what to look for, let’s take a look at the DrRacket debugger. You bring up the debugger by clicking the Debug button, rather than the Run button. Once you click that button, you should see four panes.
The DrRacket debugger supplements the standard DrRacket user interface with two more panes, labeled “Stack” and “Variables”, as well as five buttons to step through the program. The Stack pane contains a sequence of procedure calls. You can click on any of them to see the values of the variables and parameters relevant to that call.
You will note a green arrow and circle in the body of
These represent the expression that is currently being evaluated. You
should also note the red circle in the body of
That represents a breakpoint.
As you might expect, debuggers make more sense when you use them, rather than read about them. So stay tuned for lab!
Debuggers do not fix your code for you. They don’t even automatically identify your bugs. What they do is help you better understand what your code is doing. Hence, to be successful with your debugger, you need to be systematic in your debugging. Just as you would when working through the program with a partner, you need to identify what order of evaluation you expect your program to follow and what values it computes along the way. You then run through the program to see if it matches your predictions and, if not, you’ve identified a likely place where there is an error in the code.
Like programming, documentation, and testing, systematic debugging takes time and practice to master.
We’ve described a number of techniques (other than a debugger) that a programmer may use upon encountering an error. What strategy do you use when your program doesn’t work?
In most cases, we discourage students from using
instead of a debugger (at least once they’ve learned the debugger). Why
might a debugger be a better way to figure out what’s going wrong with
Robert Bruce Findler and PLT (n.d.). The DrRacket Graphical Debugging Interface. In DrRacket: The Racket Programming Environment. Available online at https://docs.racket-lang.org/drracket/debugger.html.