Debugging HLASM: Storage Dumps, IPCS, and ESTAE
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
| Abend | Code | Cause |
|---|---|---|
| 0C1 | Operation exception | Invalid instruction (bad base register, corrupted PSW) |
| 0C4 | Protection exception | Addressing storage you don't own (null pointer, bad address) |
| 0C5 | Addressing exception | Address outside valid range |
| 0C6 | Specification exception | Misaligned operand for L/ST/M/D |
| 0C7 | Data exception | Invalid packed decimal (non-digit or non-sign nibble) |
| 0C8 | Fixed-point overflow | Arithmetic overflow with mask enabled |
| 0CA | Decimal overflow | Packed decimal result too large for field |
| 0CB | Decimal divide | Packed 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:
PSW AT TIME OF ERROR 0785C000 80ABC123The instruction address is the right word: X'80ABC123'. Strip the high bit for AMODE 31: X'00ABC123'.
Registers at time of error:
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:
IPCS SUBCOMMANDCommon IPCS commands:
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 dumpDiagnosing a 0C4 (Protection Exception)
A 0C4 means you tried to access storage you don't own. Common causes:
* 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 0ESTAE — Extended Specify Task Abnormal Exit
ESTAE lets your program intercept abends and attempt recovery:
* 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 mappingInserting Debug Code
* 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 CL8Frequently 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.
