Hour 12: Boo Boo Management, Part 2 - Debugger Boogaloo

This lesson is to teach you about the debugger in Quorum.

Overview

Errors happen during the programming process. They are normal and expected. Not having any errors in a program is less normal than having them. One kind that was already discussed is the compiler error, which occurs when code does not follow the rules of the programming language and cannot be run. These kinds of errors can be found automatically by the computer. There is a different, trickier, kind of error that can be much harder to find: the runtime error. In this lesson, you are going to learn how to use a debugger to find and try to fix runtime errors. To do this, you will learn about debugging, then engage in a stump the teacher exercise.

Goals

You have the following goals for this lesson:

  • Learn about the Observe, Hypothesize, Modify, and Test cycle
  • Learn how to use the debugger to step through programs
  • Practice with a stump the teacher exercise

Warm up

Think about your experiences with real-world software. Have you encountered problems or bugs while using software? What were they? What kinds of problems have been the most or the least troublesome for you in practice?

Vocabulary

You will be learning about the following vocabulary words:

Vocabulary
TermDefinition
Compiler ErrorA mistake in a computer program where the programming language can automatically detect a problem exists
Runtime ErrorA mistake in a computer program where the program correctly compiles, but when running it has a problem (e.g., it crashes, calculates incorrectly)
DebuggerA tool used to try to find problems with the runtime behavior of a computer program.
LoggingThe act of tracking information about how a program runs.

Code

This lesson builds on debugging skills, but does not add new code constructs.

CSTA Standards

This lesson covers the following standards:

  • 3A-AP-13: Create prototypes that use algorithms to solve computational problems by leveraging prior student knowledge and personal interests.
  • 3A-AP-16: Design and iteratively develop computational artifacts for practical intent, personal expression, or to address a societal issue by using events to initiate instructions.
  • 3A-CS-03: Develop guidelines that convey systematic troubleshooting strategies that others can use to identify and fix errors.
  • 3A-AP-22: Design and develop computational artifacts working in team roles using collaborative tools.
  • 3A-AP-23: Document design decisions using text, graphics, presentations, and/or demonstrations in the development of complex programs.

Explore

Computer scientists have a difficult job. In theory, they create software for everyone, for every type of automated task. They have to be usable by everyone, regardless of age, expertise, gender, disability, or other factors. Given how common computer software is, it is inevitable that even real software may have mistakes in it. In practice, the software you use every day does not have compiler errors (at least, not by the time it reaches you). If software is on an app store, for example, it is guaranteed to never have a compiler error. If it did, it could never make it to an app store in the first place. However, software in practice can have problems and these always, without exception, come in the form of runtime errors.

Runtime Errors Again

The basic idea of a runtime error, as described previously, is that a program does something unexpected. In some cases, it may crash, while in others it may give the wrong answer or have some kind of strange behavior. A runtime error can be anything from an incorrect calculation to something looking or sounding out of place. The wide variety of problems, or bugs, can make it difficult to find.

With runtime errors: you need a plan. While it is okay to tinker, being organized can help. As an example, Rich et al. [1] have a somewhat historical, but useful and general, lens for especially young students. They suggest you debug in a cycle with the following steps: Observe, Hypothesize, Modify, and Test.

Observe

While it sounds simple, your extensive training at Bogmorts notwithstanding, there is no magic with debugging. Some bugs are just hard to find, no matter what you do. For students, you might try something like running a small program and observing what happens. In a professional setting, you might try "logging", the process of recording detailed information about a program’s execution, in order to observe what happened previously. This kind of logging, a form of observation, is very common on a web server and it can be difficult, if not impossible, to debug programs in practice without some kind of logging.

Hypothesize

After observing, the next step in debugging a program is to think through possible causes of a runtime error. This does not have to be a formal process. Even asking yourself a simple question like, "Why is this program breaking?" or "Where do I think this problem is happening?" may help think through the problem.

Modify

Once you have identified possible causes of a runtime error, you have to change the code. Changes can be as small as one character or may involve hundreds of files. How to change the code to fix an error can vary widely and depends on what you are trying to fix.

Test

The last step in the cycle is to test if a modification had the desired effect. Sometimes this can be easy to identify, for example if a program stops crashing. Other times, you may have incorrectly hypothesized what the problem was. For example, perhaps a program is based on the computer's clock and only crashes on Leap Year, but you thought the cause had something to do with holidays. Once you have tested, you may need to start the cycle fresh and try again if the bug is not resolved.

A Practical Guide to Using a Debugger

Examine the program below. Similar to one in a previous lesson, it has a divide by zero error

This shows an image with the following code:

integer a = 0
output 5 / a

In this case, the left hand side of the palette shows information about the output block, which has the focus.

This program does not have any compiler errors, which you can verify by running it. While the program runs, it crashes with an error saying it cannot process a number divided by zero. Trying to fix it might involve the following steps:

  • Observe: the program crashes with a rather complicated error message. Unfortunately, when programs crash, the error messages they give out can be extremely difficult to read or understand.
  • Hypothesize: perhaps if the variable "a" was not zero, it would not crash.
  • Modify: change the variable a to 1.
  • Test: the program no longer crashes. This does not guarantee the program is fixed, but hey it does not crash.

Another approach for observing a program is to use the debugger. To do so, you first must set a breakpoint, either by clicking on the number line with the mouse at the line you want to stop, or through COMMAND + K on Mac or CTRL + K on Windows. Next, start the debugger, either by clicking the green bug symbol, or by pressing COMMAND + D on Mac or CTRL + D on Windows. The program will start, and then stop at the breakpoint selected. This leads to a program with the following state:

This image shows the same code, except that now on line there is a green line over the line of code

Once at a stopping point, you can take several actions, like so:

This image shows the debugging controls. These are a green bug, start debugger, a red square, stop the debugger. The next five controls are pause, continue, which are two upward lines and two rightward triangles respectively. Finally, there are three arrows, one going to the right, step over, one going down, step into, and one going up, step out.

Start Debugger

This button is a green bug and starts the debugger. If no breakpoints are set, it will either run forever, if your program runs forever, or stop when your program stops. It is impossible for any computer program to know if your program will run forever or not, a finding made famous by the computer scientist Alan Turing.

Stop Debugger

This button is shaped like a red square with rounded corners and stops a program if it is running.

Pause Debugger

The pause button looks like two thick vertical lines. If a program is running in the debugger, this button will try to pause the running program. Pause is generally not used much in debugging.

Continue

The fast forward button looks like two rightward triangles stacked on each other with a vertical line at the end. It tells the debugger to run the program until the next breakpoint. If there is no next breakpoint, it will run forever or stop when your program stops.

Step Over

This button is a right arrow. It tells the debugger to jump over one, and only one, line of code.

Step Into

This button is a down arrow. It tells the debugger to jump inside of an action if it is applicable. In the case of the previous example, because the line of code is just assigning a value to a variable, it will have the same effect as step over.

Step Out

This button is an up arrow. It tells the debugger to jump out of an action. In the previous example, it would jump to the end of the program.

HotKeys

The following hotkeys can also be used to access the debugger commands:

Keyboard Commands for the Debugger
OperationCommand
Start DebuggerCOMMAND + D or CTRL + D
Stop DebuggerCOMMAND + E or CTRL + E
Pause DebuggerCTRL + F7
ContinueCTRL + F8
Step OverCTRL + F9
Step OutCTRL + F11
Set BreakpointCOMMAND + K or CTRL + K

[1] Kathryn M. Rich, Carla Strickland, T. Andrew Binkowski, and Diana Franklin. 2019. A K-8 Debugging Learning Trajectory Derived from Research Literature. In Proceedings of the 50th ACM Technical Symposium on Computer Science Education (SIGCSE '19). Association for Computing Machinery, New York, NY, USA, 745–751. https://doi.org/10.1145/3287324.3287396

Engage

In this section, you will participate in a game of Stump the Teacher. This idea, originally adapted from Kerslake [2], is to write programs that you believe are correct, intentionally add bugs to them, and then a friend or the instructor thinks out loud while trying to debug them. Be devious. Have fun.

Directions

In the stump the teacher exercise, you will modify the provided example program. Read the next section to learn about the program, then change it to purposefully add bugs to it. Because the example program includes actions and complex conditionals, you might find the debugger helpful for understanding how the program runs.

The Sorting Hat Program

At Bogmort’s School of Mathcraft and Calculatry, first-year students are placed into houses after their first set of exams. These houses provide a community for each student for the remainder of their education with Bogmort’s. In the past, students were sorted using a supposedly magical hat, but in modern times, you write software.

There are four houses at Bogmort’s: Graphingdor, Sinetherin, Ratioclaw, and Hyperbolapuff. Before a student is sorted into a house, their grades are recorded for their Potions, Math, and Flying classes. Based on these grades, students are sorted according to these rules:

  • If a student’s Flying grade is higher than their other two grades, they go into Sinetherin.
  • Otherwise, if a student’s Math grade is 90 or higher and their Flying is less than 80, they go into Ratioclaw
  • Otherwise, if all three of their grades are 75 or higher, they go into Graphingdor.
  • Finally, any remaining students go into Hyperbolapuff.

There is one special exception: if a student’s first name begins with "H" and their last name starts with "P", they are sorted into Graphingdor, according to the school’s cheesy and esoteric "Chosen One" rule.

There are several students who are ready to be sorted into houses. The table below shows their names, grades, and expected house.

Student Information
StudentPotionsMathFlyingHouse
Craigric Dingery705954Hyperbolapuff
Harmony Grander9910080Graphingdor
Decco Milford796890Sinetherin
Henry Porter506094Graphingdor
Chloe Pang819076Ratioclaw
Ram Westley907590Graphingdor

Take a few minutes to look at the provided program below. It will evaluate the six students and sort them into their houses. You can also download this program template.

You are also free to copy and paste the code below into Quorum Studio.

class SortingHat
    action Main
        text craigricHouse = SortStudent("Craigric","Dingery", 70, 59, 54)
        text harmonyHouse = SortStudent("Harmony","Grander", 99, 100, 80)
        text deccoHouse = SortStudent("Decco","Milford", 79, 68, 90)
        text henryHouse = SortStudent("Henry", "Porter", 50, 60, 94)
        text chloeHouse = SortStudent("Chloe","Pang", 81, 90, 76)
   	 text ramHouse = SortStudent("Ram","Westley", 90,75, 90)
   	 
        AnnounceHouse("Craigric", "Dingery", craigricHouse)
        AnnounceHouse("Harmony", "Grander", harmonyHouse)
        AnnounceHouse("Decco", "Milford", deccoHouse)
        AnnounceHouse("Henry", "Porter", henryHouse)
        AnnounceHouse("Chloe", "Pang", chloeHouse)
        AnnounceHouse("Ram", "Westley", ramHouse)
    end
    
    action SortStudent(text firstName, text lastName, integer potionsGrade, integer mathGrade, integer flyingGrade) returns text
        text house = ""
        if firstName:StartsWith("H") and lastName:StartsWith("P")
            house = "GRAPHINGDOR"
        else
            if flyingGrade > potionsGrade and flyingGrade > mathGrade
                house = "SINETHERIN"
            elseif mathGrade >= 90 and flyingGrade < 80
                house = "RATIOCLAW"
            elseif potionsGrade >= 75 and mathGrade >= 75 and flyingGrade >= 75
                house = "GRAPHINGDOR"
            else
                house = "HYPERBOLAPUFF"
            end
        end
        return house
    end
    
    action AnnounceHouse(text firstName, text lastName, text house)
        output "I hereby place " + firstName + " " + lastName + " into... " + house + "!"
    end
end

Break Your Program

You do not have to use this program. You can also write your own, find one online, or whatever works for you. Once you have read through the program, break it. You may add any kind of error you would like, including both compiler errors or runtime errors. You could break the code so it does not compile, or you could purposely make it crash when it is run. You could tweak the conditions so students are sorted into the wrong houses. While the goal is to stump the teacher, the more crucial goal is to have some fun with debugging.

Once you have broken your code, write a sentence or two secretly to document how you broke it and the fix, but do not tell the teacher. You will then pass your code off to a teacher or friend to fix.

Talk Aloud

If done in a class setting, select one or more projects to try and stump the teacher. If there is more than one teacher, friend, or expert, then be creative on the strategy that works best for your situation. For example, you might have two experts debugging different groups separately or hold a competition for the hardest bug to fix.

As the teacher tries to fix a bug, they should talk out loud and describe the process they are going through, whether formal or not. If they forget, or stop to think, others in the room should politely prod, or perhaps humorously taunt, the teacher to state their thoughts out loud. The purpose is for the teacher to share the process live with students to help them learn effective (or not) strategies.

Wrap up

Complete the three steps for the exercise. If time allows, have a full group reflection on the strategies that helped the most or the least.

[2] Chris Kerslake. 2024. Stump-the-Teacher: Using Student-generated Examples during Explicit Debugging Instruction. In Proceedings of the 55th ACM Technical Symposium on Computer Science Education V. 1 (SIGCSE 2024). Association for Computing Machinery, New York, NY, USA, 653–658. https://doi.org/10.1145/3626252.3630934

Next Tutorial

In the next tutorial, we will discuss Actions and Classes, Part 2, which describes how to create classes in Quorum.