Debugging Tips
When a program does not perform as intended, we say it has one or more bugs (defects). The art of tracking down and fixing these defects is known as debugging.
This page presents some tips for debugging Mini Micro programs.
Contents
Check Your Assumptions
Most bugs are fundamentally the result of something you believe or assume, which is not actually true. As you go over your code, look for ways to check your assumptions. (The methods below can help.)
Print to the screen
To verify that your code is doing what you think it's doing, it's often helpful to use print
liberally.
To check the results of some frequent (e.g. every-frame) calculation, sometimes it's helpful to print this in the same part of the screen as a constantly-updating display. For example:
text.row = 25
print "Mouse: " + mouse.x + "," + mouse.y + " " * 30
(The extra " " * 30
pads the output with spaces for cases where the new output is shorter than the previous output.)
Print to a log list
If your debug output is too long and complex to see on screen, or the text display is hidden or too busy to allow this, then you can instead log your output to a list. Just put debugOut = []
at the start of your program, and whenever you have anything interesting to note, push it onto this list, e.g. debugOut.push "Starting calculation at " + time
.
Then, after stopping your program, you can inspect this in various ways. The pageThrough
function (defined in /sys/lib/startup.ms
) may be helpful. For example, to page through the last 100 lines of your debug output, you would do pageThrough debugOut[-100:]
. Or, write to a file with file.writeLines "debug.txt", debugOut
, then inspect the resulting file with a text editor.
Use stackTrace
When your program breaks with an error message while running, use the stackTrace command to see how it got into that state. (Available in Mini Micro and Farmtronics.)
Use the QA module
In Mini Micro and Farmtronics, there is a qa
(Quality Assurance) module in /sys/lib
that may be imported. This provides functions like abort
, assert
, and assertEqual
. Add these to check your assumptions, for example:
- At the start of a function, assert that the function arguments are of the correct type and range.
- After calling a function, assert that the returned value is what you expect.
- Validate a complex data structure, and call
abort
if anything fails to add up.
When an assertion fails or abort
is explicitly called, the qa
module will display the error and a traceback, in red text over a dark (but translucent) background. This lets you know immediately that there was a problem, something about what the problem was, and where it occurred. You can enter qa.clear
to clear this error display.