Chapter 20: Debugging Techniques and Tools -- Key Takeaways

Chapter Summary

Debugging COBOL programs requires a combination of disciplined coding practices, systematic analysis of compiler and runtime output, and effective use of platform-specific debugging tools. This chapter covered the full spectrum of debugging approaches available to COBOL programmers, from the simplest DISPLAY-based tracing to sophisticated interactive debuggers that allow step-by-step execution, variable inspection, and conditional breakpoints.

The most fundamental debugging technique in COBOL is the DISPLAY statement, which writes data values to SYSOUT or the console at strategic points in the program. While simple, well-placed DISPLAY statements remain one of the most effective debugging tools because they work on every platform, require no special setup, and can be quickly added and removed. We examined patterns for structured debug output that includes timestamps, paragraph names, and key data values, making it easy to trace program flow through complex logic.

Beyond DISPLAY, COBOL provides the USE FOR DEBUGGING declarative, which can be activated with the WITH DEBUGGING MODE clause to automatically trace paragraph and section execution. The READY TRACE and RESET TRACE statements offer similar capabilities in some compiler implementations. We then moved to compiler listing analysis, which is often the single most productive debugging activity: reading the cross-reference listing, the data map, and the generated code offsets allows programmers to correlate abend addresses with specific source statements. The chapter concluded with coverage of platform-specific tools, including IBM Debug Tool (now IBM z/OS Debugger) for Enterprise COBOL on z/OS and GnuCOBOL's cobcrun debugging capabilities for open-source environments, along with techniques for analyzing common abend codes such as S0C7, S0C4, and S0C1.

Key Concepts

  • DISPLAY is the most universally available debugging tool in COBOL; it writes data item values to SYSOUT (z/OS) or standard output (open-source platforms) at runtime.
  • Structured debug output should include a timestamp (from FUNCTION CURRENT-DATE), the paragraph or section name, and the key data values being traced, formatted for easy visual scanning.
  • The WITH DEBUGGING MODE clause in the SOURCE-COMPUTER paragraph activates debugging lines (lines with "D" in column 7) and the USE FOR DEBUGGING declarative.
  • USE FOR DEBUGGING is a declarative in the DECLARATIVES section that fires automatically when the specified paragraph, section, or data item is referenced during execution.
  • The special register DEBUG-ITEM contains sub-fields including DEBUG-LINE, DEBUG-NAME, and DEBUG-CONTENTS that identify what triggered the debugging declarative.
  • READY TRACE activates automatic paragraph-level tracing, and RESET TRACE deactivates it; these are supported by some compilers including GnuCOBOL.
  • The compiler listing is a critical debugging resource containing the source listing with line numbers, the cross-reference listing, the data division map, and diagnostic messages.
  • The cross-reference listing shows every data item and procedure name along with the line numbers where each is defined and referenced, helping locate unused or incorrectly referenced items.
  • On z/OS, abend codes such as S0C7 (data exception), S0C4 (protection exception), and S0C1 (operation exception) indicate specific categories of runtime failure.
  • The offset in an abend message can be matched against the compiler listing's condensed verb listing or assembler expansion to identify the exact COBOL statement that failed.
  • IBM z/OS Debugger (formerly Debug Tool) provides interactive breakpoints, variable inspection, COBOL-aware expression evaluation, and the ability to modify data values during execution.
  • GnuCOBOL supports debugging through the -debug and -fdebugging-line compiler flags, and programs can be run under the cobcrun runtime with debugging enabled.
  • Condition handling through the DECLARATIVES section and the USE AFTER STANDARD ERROR procedure allows programs to intercept file I/O errors and take corrective action instead of abending.
  • Compile-time debugging includes using the FLAG compiler option to detect nonstandard or deprecated features and the SSRANGE option to detect out-of-range subscript references.

Common Pitfalls

  • Leaving debug DISPLAY statements in production code: Debug output left in production programs wastes I/O resources, can expose sensitive data, and clutters system logs. Use compiler debugging lines (D in column 7) or conditional compilation to manage debug output.
  • Ignoring compiler warnings: Compiler diagnostic messages at the Warning (W) and Informational (I) levels often flag potential problems such as unreferenced data items, truncation, or implicit type conversions that become runtime errors.
  • Misinterpreting the abend offset: The offset in an abend message is relative to the beginning of the program's load module, not the source listing line number. You must use the compiler listing's offset map to translate.
  • Failing to compile with debugging options: The SSRANGE, TEST, and LIST compiler options must be specified at compile time to enable subscript checking, debugger support, and assembler listing generation. They cannot be added after the fact.
  • Debugging the wrong version of the source: When the source listing does not match the currently running load module, all offset-based diagnosis is invalid. Always verify that the compiler listing corresponds to the executing program.
  • S0C7 with packed-decimal fields: The most common COBOL abend occurs when a COMP-3 (packed-decimal) field contains invalid data, often because it was not initialized or was overlaid by alphanumeric data. Always initialize numeric fields.
  • Overlooking the DECLARATIVES section: Many programmers handle file errors through inline status-code checking but forget that the DECLARATIVES section can catch errors that would otherwise cause abends, especially for unexpected I/O failures.
  • Not testing with boundary data: Many bugs only manifest with boundary values such as zero-length strings, maximum-value numerics, or end-of-file conditions. Systematic boundary testing catches problems that normal data misses.

Quick Reference

      * DISPLAY-based debugging
           DISPLAY "DEBUG: 1000-PROCESS-RECORD"
               " CUST-ID=" WS-CUST-ID
               " BALANCE=" WS-BALANCE

      * Conditional debug lines (D in column 7)
      D    DISPLAY "DEBUG: ENTERED 2000-VALIDATE"
      D    DISPLAY "DEBUG: WS-STATUS=" WS-STATUS

      * Enable debugging mode
       SOURCE-COMPUTER. IBM-390 WITH DEBUGGING MODE.

      * USE FOR DEBUGGING declarative
       DECLARATIVES.
       DEBUG-SECTION SECTION.
           USE FOR DEBUGGING ON 1000-PROCESS-RECORD.
       DEBUG-PARA.
           DISPLAY "TRACE: " DEBUG-NAME
                   " LINE: " DEBUG-LINE.
       END DECLARATIVES.

      * READY TRACE / RESET TRACE (GnuCOBOL)
           READY TRACE
           PERFORM 1000-PROCESS-RECORD
           RESET TRACE

      * File error declarative
       DECLARATIVES.
       INPUT-ERROR SECTION.
           USE AFTER STANDARD ERROR PROCEDURE
               ON INPUT-FILE.
       INPUT-ERROR-PARA.
           DISPLAY "FILE ERROR: STATUS=" WS-FILE-STATUS
           STOP RUN.
       END DECLARATIVES.

      * Compiler options for debugging (z/OS JCL)
      *  PARM='TEST,SSRANGE,LIST,XREF,MAP,OFFSET'

What's Next

Chapter 21 addresses COBOL coding standards and best practices, providing guidelines for naming conventions, paragraph organization, structured programming techniques, and documentation standards. The debugging techniques covered in this chapter become significantly easier to apply when programs follow consistent coding standards, because well-named data items, logically structured paragraphs, and clear documentation make it faster to locate and diagnose problems in any COBOL program.