Anti-bugging is an approach to testing where the design is set up in such a way that error conditions can be anticipated and error-handling paths set up to reroute or cleanly terminate processing when an error does occur. This is an extremely effective way to provide built-in debugging assistance when an error is uncovered. Unfortunately, there is a tendency to incorporate error handling into software and then never test it.
Guidelines for Anti-Bugging
From the very beginning of the project, thorough documentation should be enforced. When the programmer is forced to document, he is consequently forced to look at the logic of the program - the big picture as it were – and not get caught up in the details of the implementation. This also facilitates debugging later, both for the programmer of the code and any other programmers that might have to work on that code.
Input checking should be a consistent practice, both for input from the user and input from other programs. If inaccurate, incomplete or incorrectly formatted data is allowed into the system, errors and incorrect output become inevitable. Thus, the programmer should implement procedures that do not allow the program to continue until the input is accurate and complete. There are several parameters to consider when checking input:
-Ensure that the correct data type is input.Many errors can be anticipated during a program’s implementation. The programmer(s) need to look for potential trouble spots where errors might occur. These trouble spots can appear for several reasons:
-Incorrect input data, either from users or another programIn order to avoid premature termination of a program, most errors will have to be checked for before they occur. Since not all errors are predictable, this is not always possible. However, in the case where these errors can be anticipated, preventing them from happening forces the utilization of the programmer’s error handling routines instead of the system defined routines. Program execution can continue and, if the programmer has followed the guidelines governing error descriptions, debugging can proceed more efficiently. Some languages contain a try/catch construct for handling errors. Using these constructs in the implementation can facilitate bug catching.
When the error is discovered, a decision needs to be made as to whether the program needs to terminate execution, or if it can continue. This decision is affected not only by the importance of the integrity of the data, but also might be affected by the type of error found or where and when the error occurred. This decision can be implemented within the error handling routines.
If the program can be allowed to continue execution, then procedures need to be implemented to facilitate the continuation while maintaining data integrity and program correctness. This could be implemented by keeping a data log that is updated periodically and time-stamped so that the most recent data before the error can be recalled. The programmer could also implement this by writing a procedure to allow the user to step through the program and input the data until it is all recovered.
Sometimes program termination is inevitable. Either data integrity is too important or the program is in such an unsafe state when the error occurs that it cannot continue safely. In this case, any information important to debugging can be output. Both the error information and perhaps the data itself can be output to a log file for use by the programmer. It would also be helpful to output a dump file of the memory and registers at the time of the error.
When an error is output, clarity and precision is of utmost importance. Error explanations need to be explicit and concise, so that corrections can be made quickly without the programmer having to wonder about the cause of the error. This explicitness can be maintained by coding precise and appropriate error-handling procedures that specify the type of error encountered. It would also be helpful to output the lines of code involved, and if possible, the data involved. A dump of the memory and the state of the registers should also be output in case the previous information is inadequate.
Advantages of Anti-Bugging
The primary advantage to anti-bugging is that it saves both time and money in the long run. Errors caught later in development are paid for four different times:
This results in more time and more money spent on developing the product. There is an added cost benefit in that it is easier and more efficient to implement the error checking and handling code as the software is being developed than if the code is added at a later time. Also, since anti-bugging occurs simultaneously with implementation, the erroneous code being fixed is still fresh in the programmer’s head, thus less time is spent reading documentation and reminding one’s self of what has been done.
Disadvantages of Anti-Bugging
One of the primary disadvantages to anti-bugging is that it can be overdone, thus unnecessarily increasing production time. Sometimes the cost involved in anti-bugging is too great compared to the cost of just letting minor bugs continue to exist. Also, when taken to the extreme, the time spent on code for error handling could far outweigh that for the actual program. Even if the code error-handling code does not outweigh that of program code, the effort still makes the implementation much more complex.