We know that the program is correct, because we designed it correctly. M. A. Jackson, ‘Principles of Program Design’
Aims
The aims of this chapter are:–
• to introduce some of the common ways that errors get into pro - grams
• to look at some of the ways the computer system can help in the process of error detection and correction
Introduction
Errors are due to a wide variety of causes. They may include simple typing errors, incorrect use of certain statements, logic errors etc. The computer system can help you in a variety of ways in the error detection and correction process. The computer system can help detect errors at two stages. These are:–
• At the compilation stage
The methods at this stage involve the selection of
compiler options, and the use of an up-to-date listing
of the program.
• At the execution stage
Again, the method generally depends on a choice of
compiler options, but now there may be the opportu-
nity to use another program, sometimes given the name post-mortem dump, and on some systems there is the possibility of using an interactive de-
bugger.
Facilities like those described below should be available on most systems.
The compilation process
In the first chapter it was stated that one of the things that a compiler does is to take a program written in a high level language and produce a set of machine level instructions that can be executed by the hardware. In fact, this is only one of a possibly large number of things that a compiler can do. Let us now con - sider some of the other functions of a compiler, particularly those which may help in error detection and correction.
Compiler options Error trace back
What this means is that when an execution error occurs, there will be code added to your program that will try to work back from where the error caused the program to blow up to where the error may have been generated. Note that an error can occur quite early on in a program and take a considerable while before it has a serious and noticeable effect.
Array checking
Cause array bounds to be checked. An array going out of bounds is one of the most common errors in Fortran programming. For example, if a program calcu - lates the index for an array reference, in order to place information into that array, it is possible for the program to go outside the memory set aside for the
array. This means that the program could be over-writing itself. This kind of error is not always trapped and diagnosed by Fortran compilers.
String checking
Turn on the checking of sub-string operations on character data. This kind of error can be very difficult to find sometimes.
Post-Mortem Dump
Switch on the post-mortem dump. If your program goes wrong at execution time another program will try and work out where your program went wrong. This option requires the compiler generated symbol tables to be available. Sym- bol tables are compiler generated files. They are used in a variety of ways at the compilation stage. They can also be of use at the execution stage by other programs. The contents of a symbol table may be all of the variables with a list of the variable attributes, e.g. real, integer etc. These tables enable the post- mortem dump program to come in after your program has gone wrong and give you useful information regarding the state of your program at the time it went wrong. Another file that needs to be available is the load or linker listing. This is a listing file containing information about where variables etc. are actually to be found in memory. When you reference an array, for example, there will be a storage location associated in the linker listing.
Debug
Make available a run-time de-bugging environment. This enables your program to be interrupted and values of variables to be printed out or even changed. The beauty of this option is that no changes to the program are necessary, you interact with your program through the de-bugging program. This facility is simple yet powerful, and can save considerable amounts of time when de-bug - ging large programs.
Listing options
The compiler generates a file, the contents of which are discussed in more detail below, called a listing file. This information can be written to the termi - nal or to a file. Whilst working at a terminal it is possible to write this information to a file and then send the file to be printed.
When the compiler gives extra information and diagnostics it refers to the source. Hence an up-to-date listing is essential. Most people do not generate an up-to-date source listing each time they compile However, if you are trying to find bugs in your program, it makes no sense at all not to work from an up-to-date listing, reflecting the program at the time it went wrong. Often you will make small changes which you think do not cause any problems.
However, changing programs tends to make them go wrong, and you should always work from an up-to-date listing when trying to find errors.
We would want the listing to contain at least
• the complete source
• a list of all variables functions etc with their type
• a cross reference of all variables and where they occur in the pro - gram.
It is also useful with large programs if the listing has page numbering, and that each function (or subroutine) starts on a new page — it makes the listing easier to use, and locate information.
Optimise off
When developing programs there is no point getting the compiler to optimise your program when there are going to be errors. Optimisation is considered more generally in Chapter 21.
Summary
This chapter has looked at the kinds of facilities you could expect to be avail - able when debugging programs.
There will probably be debugging aids available on your machine that have direct counterparts to the ones mentioned above, and really it is up to you to see what your system has to offer in this area.
Problems
1. Find out what options there are when compiling your program. In what way are they similar to the ones mentioned in this chapter? In what ways are they different?