If poring over vast amounts of source code is not the best strategy, then what is?
For many years I put landmarks, or hello checkpoints, all through a long or complex program. I called these landmarks the Harkins Trace; they output a trace of all audited statements and the data being processed to disk for my analysis.
I reasoned that if the traditional memory dump that was caused by a programs abnormal termination, or abend, was so valuable to the programmer because it showed the contents of memory at the point-of-failure, then tracing every important function or routine, including the data, would add worlds of useful information to programs as they executed normally.
I was right. I soon found that tracing (auditing) every executing statement with its data was even better. With my Harkins Trace, I could see exactly what was executing in the program, with its variables , and thus focus on the important main-line logic of any program that I traced, without looking at the source program.
Now, many programming languages have debuggers and tracers built right into the language and the operating system. RPG, for example, on the iSeries, has an extremely powerful trace/debug facility. You can set breakpoints and turn the debugging facility on or off at will. If you are working on a system with a language that has this kind of facility, you should not only be using it, you should become an expert in it. It will make you a much more effective and efficient programmer.
I have devised a software tool that automates the Harkins Trace. When I cant use it say, on a consulting job where my tool is not availableI put in the trace manually. Heres how I do it: I make three sweeps through the program. In the first sweep, I audit (trace) file input/output. For instance, when I come across a READ statement in the program, I audit that statement. Then, every time that READ statement executes I know not only that it has in fact executed, but I can also see the data that was read.
I do the same with WRITE, UPDATE, and DELETE statements. That shows me where the input/output is.
Next I audit the conditional statements like IF. That makes it possible to see whether the statement has executed and see not only the contents of the data in the statement, but also whether the information is true or false.
Finally I take on the arithmetic and move statements, the guts of the program. For instance, for ADD, SUBTRACT, MULTIPLY, DIVIDE, MOVE, I can see that the instruction has executed, see the data used in the instruction, and learn whether the data was as I expected it to be.
As stunning as the visualization of the execution of any program and its data is, it is equally stunning for me to be able to work backward from when a program abends in order to see exactly the conditions that caused it to fail. (These conditions are almost always audited in the several pages of trace output before the abend occurs.)
After going through this procedure, I can just sit back and watch the trace output and then be able to tell exactly what went wrong with the program, and why, and best of all, how to correct it. Indeed, my audits do more. When Im dealing with something like a warehouse distribution system and, say, a packers creative packing techniques cause a glitch in the program, my trace output will identify the culprit. I can then tell my manager to provide more training for the errant packer (managers find this kind of sleuthing impressive).
I can often spend a week inserting my Harkins Trace audit statements into a key program. If you have the proper tools, that will be a week you dont have to spend . But if you dont, it is a week well spent. Providing yourself with a hello of every statement and piece of data that executed will let you master programs that it would take you much longer to masteror youd be unable to masterwithout a trace.