Inside COBOL #77 (Debugging from COBOL)
by
Shawn Gordon
President
The Kompany

Many people don’t realize that there are some built in facilities for doing debugging in a COBOL program. I’ve made use of them for years, but sometimes you forget that other people may not be using them. I had just been thinking about covering this topic, and suddenly I got an email from Mark Wonsil at 4M Enterprises suggesting that I cover it. Great minds think a like.

The first two methods are native, and they are tied to a compile option in the ENVIRONMENT DIVISION, namely the SOURCE-COMPUTER directive. Under normal circumstances you can pretty much put whatever you want here, typically mine says SOURCE-COMPUTER HP-3000. Now to take advantage of the built in debugging features you must first make a modification to this line, it must now read:

SOURCE-COMPUTER. HP-3000 WITH DEBUGGING MODE.

Now what I do is have two lines in the ENVIRONMENT DIVISION one with, and one without the DEBUGGING clause, and just comment one out. It’s a little faster. Now the first trick you can use is by putting a D in column 7 (this is really the first usable column for COBOL under most editors if it is saved numbered. When you do this, the line is considered a comment, unless the program is compiled with the WITH DEBUGGING MODE directive. This allows you to put all sorts of code into your program for tracing and such and then be able to turn it on with a quick change and recompile.

Now of course the downside to this is that it requires a recompile to be affective. The other fun thing to use with the debugging clause is the DECLARATIVES. Now I’ve never found another use for it, but for debugging is pretty useful. Actually, if someone can tell me something else they’ve used DECLARATIVES for, I would be interested in seeing it.

Basically the first line after the PROCEDURE DIVISION has to say DECLARATIVES (see figure 1). I believe I might have got this from the COBOL manual originally, but there are some predefined variables that you can access that will give you some pretty useful information. I’ve never actually played with changing it because it always satisfied my need, as an example, I don’t know if the “USE FOR DEBUGGING ON ALL PROCEDURES” can be changed to specific procedures, but it would make an interesting experiment.

Now the nice thing about the DEBUG SECTION is that you can control it with a run time switch instead of compile time. If you look at figure 2, you will see that I run the program with PARM=1. In the example I’ve run the program twice, providing the same input both times, the program has a prompt of “B>”. The second run has the PARM=1 so you can see how the debug trace works. You will see each paragraph, the line it is on and how you got there, either fall through, perform, or go to.

This is very convenient for seeing if you have a loop somewhere or are falling through when you shouldn’t be, all sorts of things. I know it’s saved my bacon a number of times, and it is a good tool to use before getting into your source level debugger, because it will narrow down where the potential problem is much quicker than single stepping through a bunch of code.

I hope you’ve enjoyed this forray into debugging. One final note I will make is that adding the BOUNDS directive to the $CONTROL line can save your life. Bounds checking will make sure you aren’t adding a 31st table entry to a table that has only 30 entries, or you aren’t trying to put data to the zeroth byte of a character array, all sorts of neat things. I had a client with an enormous COBOL program that was having some trouble. The first thing I did was add bounds checking, and we found out they were trying to put to many entries into a table. I left them to the program, and after a couple of weeks of trying to get the program to stop failing on bounds violations, they finally decided that if they took out the bounds checking, then it wouldn’t fail, and they would be all done. I really hate to think how much corrupted data is in their system because of that decision.

Figure 1

PROCEDURE DIVISION.
DECLARATIVES.
DEBUG SECTION.
     USE FOR DEBUGGING ON ALL PROCEDURES.
000-DEBUG-TRACE.
     DISPLAY DEBUG-NAME DEBUG-CONTENTS " LINE = " DEBUG-LINE.
END DECLARATIVES.

Figure 2

The Kompany: run backtalk

BALKTALK Background Job Communicator 11.60822 Copyright 1992 SMGA

B> ?
UNKNOWN COMMAND NAME
B> help

COMMANDS: EXIT HELP KILL QUIT RESET RUN STARTJOB STATUS STOPJOB TIMER
          VERSION XEQ :MPE command %MPEX command

B> exit

END OF PROGRAM


The Kompany: run backtalk;parm=1

BACKTALK-SECT01               START PROGRAM                  LINE = 014300
A0000-DEFINE-MACROS           FALL THROUGH                   LINE = 010600
A1000-STARTUP                 FALL THROUGH                   LINE = 010600
BALKTALK Background Job Communicator 11.60822 Copyright 1992 SMGA

G1100-PROCINFO                PERFORM LOOP                   LINE = 014600
G1100-EXIT                    FALL THROUGH                   LINE = 042200
A1100-PROMPT                                                 LINE = 017700
B> ?
UNKNOWN COMMAND NAME
A1100-PROMPT                                                 LINE = 038200
B> help
H1000-HELP                    PERFORM LOOP                   LINE = 025700

COMMANDS: EXIT HELP KILL QUIT RESET RUN STARTJOB STATUS STOPJOB TIMER
          VERSION XEQ :MPE command %MPEX command

H1000-EXIT                    FALL THROUGH                   LINE = 045200
A1100-PROMPT                                                 LINE = 025800
B> exit
C9000-EOJ                                                    LINE = 024500
C9000-SKIP                    FALL THROUGH                   LINE = 039500

END OF PROGRAM
The Kompany: