Simple Mainframe Universe
Home Tutorials Interview Q&A Quiz Mainframe Memes Contact us About us

COBOL Troubleshooting


INSPECT count or replace gives wrong result

Troubleshooting guide for INSPECT count or replace gives wrong result. Logic bugs do not abend — the program runs to completion and produces wrong results, so they are found by control totals, not dumps.

What it means

  • COBOL control flow (PERFORM, GO TO, CALL) is paragraph-based, so a misplaced period or wrong paragraph range silently changes what executes.
  • Parameter bugs between programs (CALL ... USING vs LINKAGE SECTION) corrupt data without any error message.
  • Copybook and name collisions cause the compiler to accept code that does something different from what the programmer intended.

Common causes

  • Infinite loop: PERFORM UNTIL condition where the condition field is never updated inside the loop, or the update is in a paragraph that is never reached.
  • PERFORM PARA-A THRU PARA-B executes every paragraph in between, including paragraphs the programmer thought were separate.
  • Nested PERFORM: an inner PERFORM ... THRU range that overlaps the outer range causes paragraphs to execute twice or be skipped.
  • CALL USING passes 3 items but the called program LINKAGE SECTION defines 4 — the 4th item reads whatever follows in memory.
  • Copybook updated in one program but not recompiled in the caller — layout mismatch between CALLER and CALLEE.
  • Duplicate paragraph or data names: the compiler uses the first definition; the second is silently ignored (warning only).
  • 88-level condition name with overlapping values, e.g. 88 VALID VALUE 1 THRU 5 followed by 88 ALSO-VALID VALUE 5 — value 5 sets both.
  • INITIALIZE WS-GROUP clears every subordinate field including counters and flags the programmer wanted to keep.
  • STRING ... WITH POINTER: pointer not reset to 1 before the next STRING, so data is written past the intended position or overflows.
  • UNSTRING with ALL delimiter phrase missing: consecutive delimiters create empty items that shift the receiving fields.

How to diagnose

  • For loops: DISPLAY a counter every 1000 iterations, or check whether the loop-exit field is actually modified inside the loop body.
  • For PERFORM ranges: list the paragraphs between the THRU endpoints — every one of them executes, including fall-through paragraphs after the last one if there is no GOBACK/STOP RUN.
  • For CALL mismatches: compare the USING list against the LINKAGE SECTION item by item — count, order, and PIC sizes must match exactly.
  • Compile with LIST and XREF and check for duplicate-name warnings; treat every warning as a bug.
  • For 88-levels: DISPLAY the field value in hex when the condition misbehaves — the value is often not what the tester assumed.

How to fix it

  • Replace PERFORM ... THRU with explicit PERFORM paragraph-name (no THRU) or use inline PERFORM ... END-PERFORM blocks.
  • Make CALL USING and LINKAGE SECTION agree exactly; pass a single group item instead of many fields to reduce mismatch risk.
  • Recompile every program that copies a changed copybook — automate this in the build so stale modules cannot ship.
  • Reset STRING pointers (MOVE 1 TO WS-PTR) before each STRING, and check ON OVERFLOW.
  • Split INITIALIZE into targeted MOVEs, or INITIALIZE only the subgroup that really needs clearing.

Example: Safe loop and parameter patterns

PERFORM UNTIL EOF-FLAG = "Y" READ INPUT-FILE AT END MOVE "Y" TO EOF-FLAG NOT AT END ADD 1 TO WS-READ-COUNT END-READ END-PERFORM. * CALL "SUBPROG" USING WS-CUST-GROUP ON EXCEPTION DISPLAY "CALL FAILED" END-CALL.

Inline PERFORM keeps loop control visible; passing one group item keeps CALL and LINKAGE SECTION in sync.

Interview tip

  • Q: A program produces wrong totals but never abends. It uses PERFORM ... THRU and CALLs a subprogram. Where do you look first?
  • A: I check the PERFORM THRU range first, because it executes every paragraph between the endpoints — often more than intended. Then I compare the CALL USING list against the subprogram LINKAGE SECTION field by field, since a count or size mismatch silently corrupts data.

Prevention checklist

  • Prefer inline PERFORM ... END-PERFORM over paragraph THRU ranges.
  • Pass one group item on CALL USING instead of long field lists.
  • Compile with SSRANGE and TEST options in QA to catch subscript and logic errors early.
  • Reconcile control totals (record counts, hash totals) between input and output on every run.




© copyright mainframebug.com
Privacy Policy
MainframeBug Assistant