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:
- Limits output to only the suspicious records (not all 500,000)
- Shows the before and after values of all variables involved in the interest calculation
- Captures enough context to identify the pattern (account type, loan amount range, interest rate)
- 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:
- Using IBM Debug Tool with a batch command file
- Using Language Environment runtime options
- 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:
- Support configurable log levels (TRACE, DEBUG, INFO, WARN, ERROR)
- Include timestamp, program name, paragraph name, and log level in each message
- Write to SYSOUT for debugging and to a log file for production monitoring
- Be activated/deactivated through a runtime parameter without recompilation
- 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:
- Read test cases from a file (each test case has input values and expected output values)
- Call the calculation module with the test inputs
- Compare actual output to expected output, allowing a tolerance of $0.01
- Report PASS/FAIL for each test case with details on failures
- 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:
- Reading the abend code and identifying the failure type
- Finding the failing instruction offset in the dump
- Locating the offset in the compiler listing
- Identifying the source line that failed
- Extracting relevant data values from the dump
- 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:
- Validates every numeric field before use
- Logs the record number and content of any record with invalid data
- Continues processing valid records
- Produces a daily summary of data quality issues
- 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:
- Checkpoint the master file between each program
- Compare checkpoint files to identify which program introduced the corruption
- Use DFSORT ICETOOL to find specific corrupted records
- 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:
- Record every input record read, with timestamp and sequence number
- Record every significant decision point (IF branches taken, EVALUATE paths selected)
- Record every output record written
- Store the recording in a sequential file
- 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.