Chapter 20 Exercises: Debugging Techniques and Tools

Tier 1: Recall and Recognition (Exercises 1-7)

Exercise 1: DISPLAY Statement Debugging

Write DISPLAY statements that would help debug each of the following situations. Include the paragraph name, relevant variable values, and contextual information.

a) A READ operation that may or may not find a record in an indexed file. b) Entry and exit of a paragraph that calculates loan interest. c) The value of loop control variables at each iteration of a PERFORM VARYING. d) A CALL to a subprogram, showing the parameters being passed and the return code received.

Solution:

a)

           DISPLAY '>>> 2100-READ-ACCOUNT'
           DISPLAY '    KEY: ' WS-ACCT-KEY
           READ ACCOUNT-FILE INTO WS-ACCT-REC
           DISPLAY '    FILE STATUS: ' WS-ACCT-STATUS
           IF WS-ACCT-STATUS = '00'
               DISPLAY '    FOUND: ' WS-ACCT-NAME
                       ' BAL=' WS-ACCT-BALANCE
           ELSE
               DISPLAY '    NOT FOUND OR ERROR'
           END-IF

b)

       3000-CALCULATE-INTEREST.
           DISPLAY '>>> 3000-CALCULATE-INTEREST'
           DISPLAY '    PRINCIPAL: ' WS-PRINCIPAL
           DISPLAY '    RATE:      ' WS-ANNUAL-RATE
           DISPLAY '    TERM:      ' WS-TERM-MONTHS
           COMPUTE WS-MONTHLY-INTEREST =
               WS-PRINCIPAL * (WS-ANNUAL-RATE / 1200)
           DISPLAY '    RESULT:    ' WS-MONTHLY-INTEREST
           DISPLAY '<<< 3000-CALCULATE-INTEREST'
           .

c)

           PERFORM VARYING WS-IDX FROM 1 BY 1
               UNTIL WS-IDX > WS-TABLE-SIZE
               DISPLAY '    LOOP IDX=' WS-IDX
                       ' VALUE=' WS-TABLE-ENTRY(WS-IDX)
           END-PERFORM

d)

           DISPLAY '>>> CALLING EDTMOD1'
           DISPLAY '    PARM1: ' WS-INPUT-FIELD
           DISPLAY '    PARM2: ' WS-EDIT-FLAGS
           CALL 'EDTMOD1' USING WS-INPUT-FIELD
                                WS-EDIT-FLAGS
                                WS-OUTPUT-FIELD
           DISPLAY '<<< EDTMOD1 RETURNED'
           DISPLAY '    RETURN-CODE: ' RETURN-CODE
           DISPLAY '    OUTPUT: ' WS-OUTPUT-FIELD

Exercise 2: Compiler Listing Identification

Match each section of an IBM COBOL compiler listing with its purpose:

Listing Section Purpose
a) Data Division Map 1) Shows paragraph names with their offsets
b) Cross-Reference 2) Shows the hex offset of each data item in memory
c) Procedure Division Map 3) Lists every identifier and where it is defined/referenced
d) Condensed Listing 4) Shows compiler options in effect
e) Options Summary 5) Shows only lines with errors

Solution: - a) Data Division Map -- 2) Shows the hex offset of each data item in memory - b) Cross-Reference -- 3) Lists every identifier and where it is defined/referenced - c) Procedure Division Map -- 1) Shows paragraph names with their offsets - d) Condensed Listing -- 5) Shows only lines with errors - e) Options Summary -- 4) Shows compiler options in effect

Exercise 3: Abend Code Recognition

Identify the most likely cause for each of the following z/OS abend codes:

Abend Code Most Likely Cause
S0C7
S0C4
S0C1
S322
S806
S013
S0CB
U4038

Solution:

Abend Code Most Likely Cause
S0C7 Data exception -- non-numeric data in numeric field during arithmetic
S0C4 Protection exception -- program tried to access invalid memory address
S0C1 Operation exception -- tried to execute invalid instruction
S322 Job exceeded CPU time limit (TIME parameter)
S806 Module not found -- CALL target not in STEPLIB/JOBLIB
S013 Dataset open error -- DCB conflict or missing DD
S0CB Division by zero in binary arithmetic
U4038 COBOL runtime error -- often file not open, bad subscript, or PERFORM range violation

Exercise 4: READY TRACE Usage

What is the purpose of the READY TRACE statement, and what are its limitations? Write a code fragment showing how to enable and disable tracing around a suspect paragraph.

Exercise 5: GnuCOBOL Debug Environment Variables

List and describe the three most important GnuCOBOL environment variables used for debugging, and show how to set them on Linux.

Exercise 6: Hex Dump Reading

The following hex dump shows the contents of a WORKING-STORAGE field defined as PIC S9(7)V99 COMP-3 (packed decimal, 5 bytes). Determine the decimal value:

Hex: 01 23 45 67 8C

What would the hex dump look like if the value were negative?

Solution:

The packed decimal format stores two digits per byte in the upper and lower nibbles, with the last nibble being the sign (C = positive, D = negative, F = unsigned).

Reading the digits: 0-1-2-3-4-5-6-7-8 with sign C (positive).

The PIC is S9(7)V99, so the implied decimal point is before the last two digits: 1234567.89 (but leading zero gives us 01234567.8, wait -- let us count: 9(7) = 7 digits before decimal, V99 = 2 digits after. Total 9 digits. Packed = 5 bytes (9 digits + sign = 10 nibbles = 5 bytes).

Value: +0123456.78

If negative, the last nibble changes from C to D:

Hex: 01 23 45 67 8D

Exercise 7: Compiler Option Identification

Which IBM COBOL compiler options should be turned on for debugging and turned off for production? Match each option with its purpose:

Option Purpose
a) LIST 1) Generates the cross-reference listing
b) XREF 2) Generates the Data Division Map
c) MAP 3) Generates assembler language expansion
d) TEST 4) Inserts hooks for interactive debugger
e) SSRANGE 5) Generates runtime subscript range checking
f) SOURCE 6) Includes source code in listing
g) OFFSET 7) Generates procedure offsets for dump analysis

Tier 2: Comprehension and Application (Exercises 8-14)

Exercise 8: Data Division Map Analysis

Given the following Data Division Map excerpt from an IBM COBOL compiler listing, answer the questions below:

LINE  SOURCE    LVL  DATA NAME              BASE   DISPL   DEFN   USAGE
 45   FD        01   TRANS-RECORD           BLF=1  000000  DS 01  DISPLAY
 46              05   TR-ACCOUNT-NUM         BLF=1  000000  DS 01  DISPLAY
 47              05   TR-TRANS-DATE          BLF=1  00000A  DS 01  DISPLAY
 48              05   TR-AMOUNT              BLF=1  000012  DS 01  COMP-3
 49              05   TR-TRANS-TYPE          BLF=1  000017  DS 01  DISPLAY
 50              05   FILLER                 BLF=1  000018  DS 01  DISPLAY
 63   WS        01   WS-WORK-AREA           BLW=0  000000
 64              05   WS-TOTAL-AMOUNT        BLW=0  000000  DS 01  COMP-3
 65              05   WS-RECORD-COUNT        BLW=0  000006  DS 01  COMP
 66              05   WS-ERROR-FLAG          BLW=0  00000A  DS 01  DISPLAY

a) What is the length of TR-ACCOUNT-NUM? How do you know? b) What is the displacement of TR-AMOUNT within the record? c) TR-AMOUNT is COMP-3. If it is PIC S9(7)V99, how many bytes does it occupy? d) What is the displacement of WS-RECORD-COUNT from the start of WS-WORK-AREA? e) If a dump shows the BLW=0 base address is X'00045A00', what is the absolute address of WS-ERROR-FLAG?

Solution:

a) TR-ACCOUNT-NUM starts at displacement 000000 and the next field (TR-TRANS-DATE) starts at 00000A (hex A = 10 decimal). So TR-ACCOUNT-NUM is 10 bytes long.

b) TR-AMOUNT is at displacement 000012 (hex 12 = 18 decimal), meaning it is 18 bytes from the start of the record.

c) PIC S9(7)V99 in COMP-3: 9 digits + 1 sign nibble = 10 nibbles = 5 bytes. We can verify: TR-TRANS-TYPE starts at 000017 (hex 17 = 23), and TR-AMOUNT starts at 000012 (hex 12 = 18). 23 - 18 = 5 bytes. Confirmed.

d) WS-RECORD-COUNT is at displacement 000006 (hex 6 = 6 decimal) from the start of WS-WORK-AREA.

e) Base address X'00045A00' + displacement X'0000000A' = X'00045A0A'.

Exercise 9: Cross-Reference Analysis

Given this cross-reference listing excerpt, identify potential bugs:

IDENTIFIER             DEFN   REFERENCES
WS-AMOUNT              64     78  92  105  112  156  201
WS-BALANCE             66     79  106  M157 M202
WS-CUSTOMER-NAME       68     93  M107
WS-DATE-FIELD          70
WS-ERROR-COUNT         72     M155  203
WS-TEMP-AMOUNT         74     M91  M111  159
WS-INDEX               76     M88  89  90  M95  96

(M = modified, no prefix = referenced)

Exercise 10: DISPLAY Debugging Strategy

A batch program processes 500,000 loan payment records but produces incorrect interest calculations for approximately 3% of accounts. You cannot use an interactive debugger because the problem only occurs with production data volumes. Design a DISPLAY debugging strategy that:

  1. Limits output to only the suspicious records (not all 500,000)
  2. Shows the before and after values of all variables involved in the interest calculation
  3. Captures enough context to identify the pattern (account type, loan amount range, interest rate)
  4. Can be turned on and off with a control card, without recompiling

Solution:

       WORKING-STORAGE SECTION.
       01  WS-DEBUG-CONTROLS.
           05  WS-DEBUG-FLAG         PIC X VALUE 'N'.
               88  FL-DEBUG-ON             VALUE 'Y'.
           05  WS-DEBUG-ACCT-LO      PIC X(10) VALUE SPACES.
           05  WS-DEBUG-ACCT-HI      PIC X(10) VALUE HIGH-VALUES.
           05  WS-DEBUG-MAX-LINES    PIC 9(5) VALUE 1000.
           05  WS-DEBUG-LINE-COUNT   PIC 9(5) VALUE 0.
           05  WS-DEBUG-TOLERANCE    PIC 9(3)V99 VALUE 0.01.

       01  WS-CALC-BEFORE.
           05  WS-BEFORE-BALANCE     PIC S9(11)V99.
           05  WS-BEFORE-RATE        PIC 9V9(6).
           05  WS-BEFORE-PAYMENT     PIC S9(9)V99.

      *--- Read debug control card in initialization
       1000-INITIALIZE.
           ACCEPT WS-DEBUG-FLAG FROM ENVIRONMENT 'DEBUG'
           IF FL-DEBUG-ON
               ACCEPT WS-DEBUG-ACCT-LO
                   FROM ENVIRONMENT 'DEBUG_LO'
               ACCEPT WS-DEBUG-ACCT-HI
                   FROM ENVIRONMENT 'DEBUG_HI'
               DISPLAY 'DEBUG MODE ACTIVE'
               DISPLAY 'RANGE: ' WS-DEBUG-ACCT-LO
                       ' TO '   WS-DEBUG-ACCT-HI
           END-IF
           .

       3000-CALCULATE-INTEREST.
      *--- Capture before values
           IF FL-DEBUG-ON
              AND WS-ACCOUNT-NUM >= WS-DEBUG-ACCT-LO
              AND WS-ACCOUNT-NUM <= WS-DEBUG-ACCT-HI
              AND WS-DEBUG-LINE-COUNT < WS-DEBUG-MAX-LINES
               MOVE WS-BALANCE TO WS-BEFORE-BALANCE
               MOVE WS-RATE    TO WS-BEFORE-RATE
               MOVE WS-PAYMENT TO WS-BEFORE-PAYMENT
           END-IF

           COMPUTE WS-INTEREST ROUNDED =
               WS-BALANCE * (WS-RATE / 1200)
           COMPUTE WS-NEW-BALANCE =
               WS-BALANCE + WS-INTEREST - WS-PAYMENT

      *--- Show results for debugging
           IF FL-DEBUG-ON
              AND WS-ACCOUNT-NUM >= WS-DEBUG-ACCT-LO
              AND WS-ACCOUNT-NUM <= WS-DEBUG-ACCT-HI
              AND WS-DEBUG-LINE-COUNT < WS-DEBUG-MAX-LINES
               DISPLAY '=== INTEREST CALC DEBUG ==='
               DISPLAY 'ACCT:     ' WS-ACCOUNT-NUM
               DISPLAY 'TYPE:     ' WS-LOAN-TYPE
               DISPLAY 'BAL BEFORE: ' WS-BEFORE-BALANCE
               DISPLAY 'RATE:       ' WS-BEFORE-RATE
               DISPLAY 'INTEREST:   ' WS-INTEREST
               DISPLAY 'PAYMENT:    ' WS-BEFORE-PAYMENT
               DISPLAY 'BAL AFTER:  ' WS-NEW-BALANCE
               ADD 7 TO WS-DEBUG-LINE-COUNT
           END-IF
           .

Exercise 11: Abend Dump Analysis

An IBM COBOL program abends with S0C7 at offset X'000A2E' in module LOANPOST. The compiler listing shows that paragraph 3200-CALC-PENALTY is at offset X'000A10' and paragraph 3300-UPDATE-BALANCE is at offset X'000A50'. The source code for 3200-CALC-PENALTY is:

       3200-CALC-PENALTY.
           IF WS-DAYS-LATE > 30
               COMPUTE WS-PENALTY-AMOUNT =
                   WS-PAYMENT-AMOUNT * WS-PENALTY-RATE
               ADD WS-PENALTY-AMOUNT TO WS-TOTAL-PENALTIES
               ADD 1 TO CT-PENALTIES-ASSESSED
           END-IF
           .

The dump shows these WORKING-STORAGE values at the time of abend:

WS-DAYS-LATE          (offset 120): F0F4F5     (DISPLAY)
WS-PAYMENT-AMOUNT     (offset 130): 00250000C  (COMP-3)
WS-PENALTY-RATE       (offset 138): 4040404040 (DISPLAY)
WS-PENALTY-AMOUNT     (offset 140): 0000000C   (COMP-3)
WS-TOTAL-PENALTIES    (offset 148): 00015075C  (COMP-3)

Diagnose the abend. What field caused the S0C7, and why?

Exercise 12: GnuCOBOL Debugging Session

Write the complete sequence of commands to compile a GnuCOBOL program with debugging enabled, run it under the GnuCOBOL debugger, set a breakpoint at a specific paragraph, inspect variables, and step through execution. Assume the source file is loan-calc.cbl.

Exercise 13: Debugging a Looping Program

A COBOL program appears to enter an infinite loop. The CPU timer eventually kills it with S322. You suspect the loop is in the main processing loop, but you are not sure which condition fails to terminate. Describe three different debugging approaches you would use to identify the exact loop, and provide the code changes for each approach.

Exercise 14: Conditional Compilation for Debug

Write a COBOL program fragment that uses the IBM COBOL compiler directive >>EVALUATE (or the COPY REPLACING technique) to include or exclude debug DISPLAY statements at compile time. Show how to compile the program with debugging on and with debugging off.


Tier 3: Analysis and Problem Solving (Exercises 15-22)

Exercise 15: Multi-Module Debugging

Program MAINPROG calls three subprograms: VALDMOD, CALCMOD, and UPDTMOD. The program produces incorrect results but no abend. The master record balance after processing is $10.00 too high for certain accounts. Design a systematic debugging approach that:

a) Determines which subprogram is producing the incorrect result. b) Traces the data flow from MAINPROG through each CALL and back. c) Identifies whether the error is in the calculation, the parameter passing, or the master file update.

Provide the DISPLAY statements you would add to each program, and the WORKING-STORAGE fields needed to support the debugging.

Solution:

      *--- In MAINPROG, before each CALL:
           DISPLAY '=== BEFORE CALL VALDMOD ==='
           DISPLAY 'ACCT: ' WS-ACCOUNT-NUM
           DISPLAY 'INPUT AMT: ' WS-TRANS-AMOUNT
           DISPLAY 'MASTER BAL: ' WS-MASTER-BALANCE
           CALL 'VALDMOD' USING WS-TRANS-RECORD
                                WS-VALID-RESULT
           DISPLAY '=== AFTER CALL VALDMOD ==='
           DISPLAY 'VALID RC: ' WS-VALID-RC
           DISPLAY 'EDITED AMT: ' WS-EDITED-AMOUNT

           DISPLAY '=== BEFORE CALL CALCMOD ==='
           DISPLAY 'INPUT BAL:  ' WS-MASTER-BALANCE
           DISPLAY 'INPUT AMT:  ' WS-EDITED-AMOUNT
           DISPLAY 'TRANS TYPE: ' WS-TRANS-TYPE
           CALL 'CALCMOD' USING WS-CALC-INPUT
                                WS-CALC-OUTPUT
           DISPLAY '=== AFTER CALL CALCMOD ==='
           DISPLAY 'NEW BAL:    ' WS-NEW-BALANCE
           DISPLAY 'INTEREST:   ' WS-INTEREST-AMT
           DISPLAY 'CALC RC:    ' WS-CALC-RC

           DISPLAY '=== BEFORE CALL UPDTMOD ==='
           DISPLAY 'KEY:        ' WS-ACCOUNT-NUM
           DISPLAY 'NEW BAL:    ' WS-NEW-BALANCE
           CALL 'UPDTMOD' USING WS-UPDATE-RECORD
                                WS-UPDATE-RESULT
           DISPLAY '=== AFTER CALL UPDTMOD ==='
           DISPLAY 'UPDATE RC:  ' WS-UPDATE-RC
           DISPLAY 'STATUS:     ' WS-FILE-STATUS

      *--- In each subprogram, at entry and exit:
      *--- (CALCMOD example)
       PROCEDURE DIVISION USING LS-CALC-INPUT
                                LS-CALC-OUTPUT.
       0000-MAIN.
           DISPLAY '    CALCMOD ENTRY'
           DISPLAY '    LS-BALANCE: ' LS-BALANCE
           DISPLAY '    LS-AMOUNT:  ' LS-AMOUNT
           DISPLAY '    LS-TYPE:    ' LS-TRANS-TYPE
           PERFORM 1000-CALCULATE
           DISPLAY '    CALCMOD EXIT'
           DISPLAY '    LS-NEW-BAL: ' LS-NEW-BALANCE
           DISPLAY '    LS-INTEREST:' LS-INTEREST
           GOBACK
           .

Exercise 16: Debugging a Sorting Issue

A SORT program runs without errors but produces output records in the wrong order. The SORT statement is:

           SORT SORT-FILE
               ON ASCENDING KEY SK-BRANCH
               ON ASCENDING KEY SK-ACCT-NUM
               USING INPUT-FILE
               GIVING OUTPUT-FILE

The first 10 records of the output show:

BRANCH  ACCT-NUM
NYC     000100
NYC     000200
NYC     001000
NYC     00050
NYC     00080
NYC     01000

What is wrong, and how would you debug and fix it?

Exercise 17: S0C4 Investigation

A COBOL program abends with S0C4 (protection exception) when processing the 15,000th record. The program worked fine yesterday with a slightly different input file. The abend occurs at the statement MOVE ACCT-TABLE-ENTRY(WS-TABLE-IDX) TO WS-WORK-AREA. Design a debugging approach to determine whether:

a) WS-TABLE-IDX is out of range. b) The table was not loaded correctly. c) The table storage was overlaid by another field.

Exercise 18: Production Debug without Source Changes

A production program is producing incorrect totals, but you cannot modify the source code (it is in a production change freeze). Describe three techniques available on z/OS to debug the program without changing the source:

  1. Using IBM Debug Tool with a batch command file
  2. Using Language Environment runtime options
  3. Using DFSORT/ICETOOL to examine the output file

For each technique, provide the JCL or commands you would use.

Exercise 19: Debugging Numeric Truncation

A financial report shows amounts ending in ".00" for every record, even though the transaction file contains amounts with cents. The DISPLAY output shows correct amounts being read from the file. Somewhere between reading and writing the report, the cents are being lost. List all possible causes of numeric truncation in COBOL and provide a systematic approach to isolate which one is occurring.

Exercise 20: COBOL/DB2 Debugging

A COBOL/DB2 program returns SQLCODE -811 (singleton SELECT returned more than one row) for some customer IDs but not others. You cannot reproduce the error in the test environment because the test data is different. Design a debugging approach that:

a) Identifies which SELECT statement is failing. b) Captures the host variable values at the point of failure. c) Determines what data condition causes the duplicate. d) Handles the error gracefully so the program can continue and report all occurrences.

Exercise 21: Debugging a File Mismatch

Two programs process the same file. Program A writes 100,000 records. Program B reads the file and gets only 99,997 records. No errors are reported. Use debugging techniques to determine where the three records went missing. Consider: file attributes, BLOCK CONTAINS, buffering, CLOSE timing, and record counting logic.

Exercise 22: Memory Overlay Analysis

The following WORKING-STORAGE layout has a potential memory overlay bug. Identify the risk and describe how it would manifest at runtime:

       01  WS-CUSTOMER-TABLE.
           05  WS-CUST-ENTRY OCCURS 500 TIMES.
               10  WS-CUST-ID      PIC X(8).
               10  WS-CUST-NAME    PIC X(25).
               10  WS-CUST-BAL     PIC S9(9)V99 COMP-3.
       01  WS-REPORT-TOTALS.
           05  WS-TOTAL-BALANCE    PIC S9(13)V99 COMP-3.
           05  WS-TOTAL-CUSTOMERS  PIC S9(5) COMP.
           05  WS-REPORT-DATE      PIC X(10).

Tier 4: Synthesis and Design (Exercises 23-28)

Exercise 23: Debug Logging Framework

Design and code a reusable debug logging framework for COBOL batch programs. The framework should:

  1. Support configurable log levels (TRACE, DEBUG, INFO, WARN, ERROR)
  2. Include timestamp, program name, paragraph name, and log level in each message
  3. Write to SYSOUT for debugging and to a log file for production monitoring
  4. Be activated/deactivated through a runtime parameter without recompilation
  5. Support filtering by log level (e.g., show only WARN and above in production)

Provide the WORKING-STORAGE definitions, the LOG-MESSAGE paragraph, and example usage in a program.

Hint: Use a numeric hierarchy for log levels (1=TRACE through 5=ERROR). Compare the message level against the configured threshold to determine whether to write.

Exercise 24: Automated Regression Test Harness

Design a COBOL test harness program that automates regression testing for a loan interest calculation module. The harness should:

  1. Read test cases from a file (each test case has input values and expected output values)
  2. Call the calculation module with the test inputs
  3. Compare actual output to expected output, allowing a tolerance of $0.01
  4. Report PASS/FAIL for each test case with details on failures
  5. Return a non-zero return code if any test fails

Provide the complete test harness program.

Hint: Define the test case file with fields for principal, rate, term, expected monthly payment, and expected total interest. Use COMPUTE to calculate the tolerance check.

Exercise 25: Post-Mortem Dump Analysis Procedure

Write a step-by-step procedure document (in COBOL comments format, suitable for inclusion as a copybook header) that a junior programmer can follow to analyze a production abend. The procedure should cover:

  1. Reading the abend code and identifying the failure type
  2. Finding the failing instruction offset in the dump
  3. Locating the offset in the compiler listing
  4. Identifying the source line that failed
  5. Extracting relevant data values from the dump
  6. Determining the root cause

Include worked examples for S0C7, S0C4, and S806 abends.

Hint: The key is mapping the PSW (Program Status Word) address in the dump to the program's load point, then subtracting to get the offset, then finding that offset in the OFFSET or LIST compiler listing.

Exercise 26: Performance Debugging

A COBOL batch program that previously completed in 45 minutes now takes 3 hours to process the same volume of data. No code changes were made. Design a debugging approach to identify the performance bottleneck:

a) Using SMF records and RMF reports to identify I/O bottlenecks b) Using the COBOL compiler LIST output to identify inefficient code patterns c) Using DISPLAY with timestamps to identify slow paragraphs d) Checking JCL parameters (buffers, block size, region size) for degradation

Provide the specific checks, commands, and code changes for each approach.

Hint: Common causes of sudden performance degradation include: VSAM CI/CA splits, dataset extent fragmentation, buffer pool contention, and batch window conflicts with CICS. Start with I/O analysis.

Exercise 27: Debugging Intermittent Failures

A COBOL program fails with S0C7 approximately once every two weeks, always at a different point in the file. The input file is different each day. Design a defensive debugging strategy that:

  1. Validates every numeric field before use
  2. Logs the record number and content of any record with invalid data
  3. Continues processing valid records
  4. Produces a daily summary of data quality issues
  5. Can be left permanently in the production code without significant performance impact

Hint: Create a reusable VALIDATE-NUMERIC paragraph that uses the NUMVAL or NUMVAL-C intrinsic function in a safe way, or uses an INSPECT TALLYING approach to check for valid characters before attempting arithmetic.

Exercise 28: Debugging with COBDUMP

Write a COBOL subroutine called COBDUMP that can be called from any program to display the hex and character representation of any data area. The subroutine should accept:

  • The data area (BY REFERENCE)
  • The length of the data area
  • A label to identify the dump in the output

The output should show 32 bytes per line with hex on top and EBCDIC characters below, similar to a TSO dump display.

Hint: Use reference modification to extract individual bytes. Convert each byte to its two-character hex representation using a table lookup. Handle non-printable characters by displaying a period instead.


Tier 5: Enterprise Integration Challenges (Exercises 29-33)

Exercise 29: Production Abend Triage

You are the on-call support programmer. At 2:47 AM you receive a page: "Job NIGHTLY01 step POST03 abended S0C7." Write the complete triage procedure you would follow, from receiving the page through resolving the issue and restarting the job. Include:

a) The first five TSO/ISPF commands you would execute b) How to locate the failing statement from the dump c) How to determine if the cause is bad input data or a program bug d) How to apply a temporary fix (input data correction) to restart the job before the 6:00 AM deadline e) The incident report you would file

Hint: Start with SDSF to view the job output and dump. Use the PSW address from the dump header, subtract the EPA (Entry Point Address) to get the offset, and find that offset in the compiler listing. Check the data at the failing instruction's operand addresses.

Exercise 30: Debugging in a CICS Environment

Explain how debugging a COBOL/CICS program differs from debugging a batch COBOL program. Cover:

a) Why you cannot use DISPLAY statements in CICS b) How CEDF (CICS Execution Diagnostic Facility) works c) How to use temporary storage queues for logging d) How to read a CICS transaction dump e) How CICS HANDLE ABEND interacts with Language Environment condition handling

Hint: CICS programs run in a shared environment. DISPLAY writes to the system console and would flood it with output from thousands of concurrent transactions. CEDF intercepts each EXEC CICS command and lets you examine parameters before and after execution.

Exercise 31: Debugging Data Corruption

A nightly batch cycle consists of five programs that process the same master file sequentially (PROG1 through PROG5). After the cycle completes, certain account balances are incorrect. Any of the five programs could be the culprit, or the corruption could result from an interaction between them. Design a systematic approach to isolate the problem:

  1. Checkpoint the master file between each program
  2. Compare checkpoint files to identify which program introduced the corruption
  3. Use DFSORT ICETOOL to find specific corrupted records
  4. Trace the corrupted records back through each program's processing

Provide the JCL and utility control statements for the checkpoint and comparison steps.

Hint: Use IDCAMS REPRO to copy the VSAM master file to sequential datasets between steps. Use DFSORT ICETOOL SPLICE to compare corresponding records across checkpoints. The delta between two adjacent checkpoints reveals which program made the change.

Exercise 32: Debugging a Distributed Processing Failure

A COBOL program on z/OS sends transaction data to a remote system via MQ Series (IBM MQ). The remote system reports that 5% of messages contain garbled data. The COBOL program's own log shows successful MQ PUT operations for all messages. Debug the problem, considering:

a) EBCDIC to ASCII conversion issues b) Message truncation due to buffer size mismatches c) Code page conflicts d) Packed decimal fields in messages intended for non-mainframe systems

Provide a diagnostic COBOL program that reads the MQ dead-letter queue, displays each message in hex and character format, and identifies the pattern of corruption.

Hint: The most common cause is packed decimal or COMP fields being transmitted in messages. These binary formats are platform-specific and will appear as garbled data on an ASCII system. The fix is to convert all fields to DISPLAY format before sending.

Exercise 33: Building a Debug Playback System

Design and code a system that records the inputs and decisions of a COBOL program so that the exact processing can be replayed later for debugging. The system should:

  1. Record every input record read, with timestamp and sequence number
  2. Record every significant decision point (IF branches taken, EVALUATE paths selected)
  3. Record every output record written
  4. Store the recording in a sequential file
  5. Provide a playback program that reads the recording and displays the processing flow

This approach is valuable when a production error cannot be reproduced in test because the specific combination of data, timing, and state cannot be recreated.

Provide the COPY member for the recording record layout, the RECORD-EVENT paragraph that the main program calls at each decision point, and the skeleton of the playback program.

Hint: Define a recording record with fields for: event type (READ/WRITE/DECIDE/CALC), timestamp, paragraph name, event detail (up to 200 bytes), and sequence number. The playback program reads the recording file sequentially and formats the events for human consumption.