Compile, link, run — and debugging S0C7
Source becomes an executable in two stages: the compiler produces an object module, and the binder turns that into a load module in a library. Then JCL runs it. Knowing which stage failed halves your debugging time.
Reading the compile listing
| Return code | Meaning | Do |
|---|---|---|
| 0 | Clean | Nothing |
| 4 | Warnings | Read them — some are real bugs |
| 8 | Errors | Fix; the object module may still be produced but is not trustworthy |
| 12 / 16 | Severe | No usable output |
The listing contains the expanded source with copybooks included, a cross-reference of every data name and where it is used, and the diagnostic messages. The cross-reference is genuinely useful: it answers 'where is this field set?' faster than searching.
Binder errors you will meet
| Symptom | Cause |
|---|---|
| Unresolved external reference | A CALLed program was not found. Check SYSLIB and the call name spelling. |
| Module too large | Rare; usually a runaway table definition. |
| Return code 4 with unresolved weak references | Often normal for dynamic calls — check your site's expectation. |
Debugging an S0C7 in five steps
- Find the offset. The abend message gives a PSW address and an offset into the failing program. Note it.
- Find the statement. Look up that offset in the compile listing's offset map to get the COBOL line number. If your site compiles with
LISTorOFFSET, this is quick. - Identify the field. The statement will do arithmetic on one or more numeric fields. One of them contains something that is not a number.
- Find the bad data. Look at the input record. Use the editor with
HEX ONto see the actual bytes: a packed field should end in a sign nibble of C, D or F, and a display numeric should be all F0–F9. - Fix the cause, not the symptom. Usually the field was never initialised, or the input record is a different layout from the one the program expects — a header or trailer record, a short record, or a file from the wrong source.
* a valid packed decimal field, PIC S9(5) COMP-3, value +12345 12 34 5C * the same field never initialised — low values 00 00 00 <- no sign nibble, arithmetic abends * a display numeric field, PIC 9(5), value 12345 F1 F2 F3 F4 F5 * the same field containing spaces 40 40 40 40 40 <- x'40' is a space in EBCDIC, not a digit
A compile-link-go job
//COMPLINK JOB (ACCT01),'COMPILE PAYSUM',CLASS=A,MSGCLASS=X, // NOTIFY=&SYSUID //COMP EXEC PGM=IGYCRCTL, // PARM='OBJECT,LIST,MAP,XREF,SSRANGE,TEST' //STEPLIB DD DSN=SYS1.COBOL.SIGYCOMP,DISP=SHR //SYSIN DD DSN=DEV.PAY.SOURCE(PAYSUM),DISP=SHR //SYSLIB DD DSN=DEV.PAY.COPYLIB,DISP=SHR //SYSPRINT DD SYSOUT=* //SYSLIN DD DSN=&&OBJ,DISP=(NEW,PASS),SPACE=(CYL,(1,1)), // DCB=(RECFM=FB,LRECL=80,BLKSIZE=0) //* //BIND EXEC PGM=IEWL,PARM='LIST,MAP,XREF,RENT', // COND=(4,LT,COMP) //SYSLIN DD DSN=&&OBJ,DISP=(OLD,DELETE) //SYSLMOD DD DSN=DEV.PAY.LOADLIB(PAYSUM),DISP=SHR //SYSLIB DD DSN=SYS1.SCEELKED,DISP=SHR //SYSPRINT DD SYSOUT=*
Common mistakes
Correcting one bad record gets tonight's run through. If the program cannot survive bad input, it will fail again next week.
Bounds checking in test catches subscript errors before production does, at a cost that does not matter in test.
The classic 'my change did nothing' — the job's STEPLIB points somewhere else. Check the STEPLIB concatenation order.
Some warnings — a moved field that will truncate, an unreachable paragraph — are real defects.
What you will see at work
- Almost no site compiles by hand-written JCL any more; you will use a change management tool that does it for you. The stages underneath are still these.
- Production compiles usually omit TEST and SSRANGE for performance, which is another reason to catch problems in test.
- Keep the compile listing for anything you are debugging. Without it, mapping an offset to a line is very slow.
Key terms
Check your understanding.
Take this lesson's quiz and save your progress. Free.