Debugging HLASM: Storage Dumps, IPCS, and ESTAE

TT

Debugging HLASM: Storage Dumps, IPCS, and ESTAE

Debugging HLASM requires reading storage dumps, understanding z/OS abend codes, and using IPCS (Interactive Problem Control System). This module covers the essential debugging skills every mainframe assembler programmer needs.

Common Abend Codes

AbendCodeCause
0C1Operation exceptionInvalid instruction (bad base register, corrupted PSW)
0C4Protection exceptionAddressing storage you don't own (null pointer, bad address)
0C5Addressing exceptionAddress outside valid range
0C6Specification exceptionMisaligned operand for L/ST/M/D
0C7Data exceptionInvalid packed decimal (non-digit or non-sign nibble)
0C8Fixed-point overflowArithmetic overflow with mask enabled
0CADecimal overflowPacked decimal result too large for field
0CBDecimal dividePacked decimal divide by zero

Reading a Formatted Dump

When a program abends, z/OS writes a formatted dump to SYSUDUMP or SYSABEND. Key sections:

PSW at time of error:

text
PSW AT TIME OF ERROR  0785C000  80ABC123

The instruction address is the right word: X'80ABC123'. Strip the high bit for AMODE 31: X'00ABC123'.

Registers at time of error:

text
GR 0-3   00000000  00000001  00AABC10  0000007F
GR 4-7   00ABC200  00ABC300  00000080  00000000
GR 8-11  00ABCD00  00000000  00ABCE00  00000020
GR 12-15 00ABC000  00ABCF00  00ABC124  00000000
  • Register 12: your base register = X'00ABC000'
  • Register 14: return address = X'00ABC124'
  • Register 13: save area address = X'00ABCF00'

Finding the failing instruction: PSW instruction address = X'00ABC123' Base register = X'00ABC000' Offset into program = X'00ABC123' - X'00ABC000' = X'123' = 291 decimal

Look at the assembly listing at offset X'123' to find the failing instruction.

IPCS — Interactive Problem Control System

IPCS is the z/OS dump analysis tool accessed via TSO:

text
IPCS SUBCOMMAND

Common IPCS commands:

text
STATUS REGISTERS      Display registers at time of abend
STATUS PSWA           Display PSW
LIST 00ABC000.100     Display 256 bytes starting at X'00ABC000'
CBFORMAT DSNAME=SYS1.DUMP01  Format a dump dataset
FIND ABCDE            Search dump for hex pattern
WHERE 00ABC123        Find what load module owns this address
SUMMARY               Print summary of dump

Diagnosing a 0C4 (Protection Exception)

A 0C4 means you tried to access storage you don't own. Common causes:

hlasm
* Bug 1: Forgetting to load the address before using it
         USING MYDSECT,10     USING is set but...
         MVC   MYFIELD,INPUT  ...reg 10 was never loaded! Accesses wrong storage.
* Fix:
         LA    10,WORKAREA    Load the actual address first
         USING MYDSECT,10
         MVC   MYFIELD,INPUT

* Bug 2: Off-by-one past end of table
         LA    4,TABLE
         LA    5,11           Loop count one too many (table has 10 entries)
LOOP     L     3,0(4)
         LA    4,4(4)
         BCT   5,LOOP         On 11th iteration, reads past table

* Bug 3: Uninitialized pointer
MYPTR    DS    A              Address field — never set before use
         L     10,MYPTR       reg 10 = X'00000000' or garbage
         MVC   0(80,10),DATA  0C4: accessing address 0

ESTAE — Extended Specify Task Abnormal Exit

ESTAE lets your program intercept abends and attempt recovery:

hlasm
* Set up ESTAE recovery routine
         ESTAE MYRECOVR,CT,PARAM=MYPARM,ASYNCH=NO

* Later, if an abend occurs, MYRECOVR is called before termination

* Recovery routine
MYRECOVR DS    0H
* On entry: reg 1 = SDWA (System Diagnostic Work Area) address
         LR    2,1              Save SDWA address
         USING SDWA,2           Map SDWA
*
* Log the abend code from SDWA
         MVC   ABNDCODE,SDWAABCC   Save abend code
*
* Retry: tell z/OS to give us another chance at a different address
         LA    15,0             Return code 0 = retry
         LA    0,RETRYADDR      Register 0 = retry address
         BR    14               Return to ESTAE handler
*
* If you can't recover:
*        LA    15,4             Return code 4 = percolate (continue abend)
*        BR    14

RETRYADDR DS   0H               Resume here after recovery
ABNDCODE DS    XL4
MYPARM   DS    A
         SDWA                   Include SDWA DSECT mapping

Inserting Debug Code

hlasm
* Trace a value to the operator console during debugging
DEBUGWTO WTO   'DEBUG: REG3=XXXXXXXX',MF=L
         ST    3,DEBUGREG
         UNPK  DEBUGHEX(8),DEBUGREG+1(4)  Format last 3 bytes
         TR    DEBUGHEX(8),HEXTAB-240
         MVC   DEBUGWTO+12(8),DEBUGHEX
         WTO   MF=(E,DEBUGWTO)

HEXTAB   DC    C'0123456789ABCDEF'
DEBUGREG DS    F
DEBUGHEX DS    CL8

Frequently Asked Questions

Q: How do I find which instruction caused a 0C7 data exception? The PSW instruction address in the dump points to the instruction after the failing one (z/Architecture updates the PSW before executing). Subtract the instruction length (2, 4, or 6 bytes) to find the actual failing instruction. Then check the operand fields for invalid packed decimal — any byte where the numeric nibble is A–F (not 0–9) in a field other than the sign position is invalid.

Q: What is the SDWA and when is it available? The SDWA (System Diagnostic Work Area) is a z/OS control block created when an abend occurs. It contains the PSW at error time, the registers at error time, the abend code, and other diagnostic information. The SDWA is passed to your ESTAE routine in register 1. It's only available during ESTAE processing — not at normal program checkpoints. Map it with the SDWA macro (from SYS1.MACLIB).

Q: Should I use ESTAE in all HLASM programs? ESTAE is appropriate for production utility programs and batch processors that need graceful error recovery — logging the error, closing files, freeing storage, and returning a non-zero condition code rather than generating a dump. For simple programs and subroutines, ESTAE is unnecessary overhead. System programs (exits, started tasks) often use ESTAE to prevent a single error from crashing the entire address space.


Part of HLASM Mastery Course — Module 19 of 22.