Tip: Changing the name of a file in the middle of a debugging session will prevent the debugger from working properly on that file.
Like the Run button, the Debug button runs the program in the definitions window. However, instead of simply running it from start to finish, it lets users control and observe the program as it executes. The interface includes a panel of buttons above the definitions window, as well as extensions to the definitions window itself.
The program starts out paused just before the first expression is executed. This is indicated in the definitions window by the presence of a green triangle over this expression’s left parenthesis.
While execution is paused, several buttons are available:
The Over button is only enabled when execution is paused at the start of an expression that is not in tail position. It sets a one-time breakpoint at the end of the expression (represented by a yellow circle) and causes the program to proceed. When execution reaches the one-time breakpoint, it pauses and removes that breakpoint.
The Out button is only enabled when execution is paused within the context of another expression. Like the Over button, it sets a one-time breakpoint and continues execution. In this case, the program stops upon returning to the context or raising an unhandled exception.
If the program is running (not paused), then only the Pause button will be enabled. Clicking it will interrupt execution and pause it. In this case, the current expression may only be known approximately, and it will be represented as a gray triangle. The other features described above will still be available.
At any time, execution may be interrupted by clicking the Stop button. However, unlike with the Pause button, stopped execution cannot be continued.
When execution is paused, the definitions window supports several additional actions:
Hovering the mouse cursor over a parenthesis may reveal a pink circle. If so, right-clicking or control-clicking (Mac OS X) will open a menu with options to Pause at this point or Continue to this point. The former sets an ordinary breakpoint at that location; the latter sets a one-time breakpoint and resumes execution. An ordinary breakpoint appears as a red circle, and a one-time breakpoint appears as a yellow circle.
Tip: If the debugged program is not a module, then the first time it is debugged, breakpoints will only become available in expressions as they are evaluated. However, the next time the program is debugged, the debugger will remember the set of breakable locations from the previous session.
Tip: Clicking the Run button after a debugging session will cause all breakpoints to disappear from the definitions window. These breakpoints are not forgotten, and clicking Debug again will restore them. However, breakpoints do not persist across restarts of DrRacket.
If execution is paused at the start of an expression, then right-clicking or control-clicking (Mac OS X) on the green triangle opens a menu with the option to Skip expression.... Selecting this opens a text box in which to enter a value for the expression. The expression is skipped, with the entered value substituted for it.
If execution is paused at the end of an expression, then the expression and its value are displayed to the left of the button bar. Right-clicking or control-clicking (Mac OS X) on the green triangle opens a menu with options to Print return value to console and Change return value.... The former displays the return value in the interactions window; the latter opens a text box in which to enter a substitute value.
Hovering the mouse cursor over a bound variable displays the variable’s name and value to the right of the button bar. Right-clicking or control-clicking (Mac OS X) opens a menu with options to Print value of <var> to console or (set! <var> ...). The former displays the variable’s value in the interactions window; the latter opens a text box in which to enter a new value for the variable.
In addition, while execution is paused, the stack view pane at the right of the DrRacket frame is active. The top of the pane shows a list of active stack frames. Mousing over a frame produces a faint green highlighting of the corresponding expression. Clicking on the frame selects that frame, which makes its lexical variables visible. The selected frame is indicated by a bold font.
The bottom of the pane shows the lexical variables in the selected stack frame.
The following screenshot illustrates several aspects of the debugger interface. The red circle before the if is a breakpoint, and the green triangle at the end of the (fact (sub1 n)) is where execution is currently paused. The expression’s return value is displayed at the left of the button bar, and the value of n is displayed in the stack view pane.
To debug a program that spans several files, make sure that all of the files are open in DrRacket. Click the Debug button in the window containing the main program. As this program loads additional files that are present in other windows or tabs, message boxes will pop up asking whether or not to include the file in the debugging session. Including the file means that it will be possible to set breakpoints, inspect variables, and single-step in that file.
Tip: A file may only be involved in one debugging session at a time. If you try to debug a file that loads another file that is already being debugged, a message box will pop up explaining that the file cannot be included in another debugging session.