RPG Tutorial: Resolving RPG Programming Problems - dump reading for RPG

I'm not sure that I should admit this, but most of the time I really enjoy an opportunity (when the timing is right, of course) to go digging into a dump.  In my earlier days I saw it as a challenge.  Sometime after that it became a matter of pride that I could work my way through a dump when many of the other programmers around me couldn't (or wouldn't).

Anyway, RPG being a bit unique as a programming language, it also has some unique approaches to using a dump to resolve a bad bug.  First, where most programs use a higher number register (usually Register 12) as a base register, the key to an RPG dump is Register 3.  When a condition exists that causes an RPG program to terminate abnormally, for example - a sequence error in an input file, the program will terminate with a User Abend (numbers in the range of 0040 to 0064 are common).  Some of these are listed in the abend list here on my site.  But just knowing why the abend occured may not be enough to resolve the problem.

The most frequent indicator of why an RPG program abended will be found by analyzing the Indicators that were on at the time of the abend, specifically the Halt Indicators.  Following the RPG source listing In the compiler output is a symbol table.  Here is the one from Example program three:

                                                  SYMBOL  TABLES
 000004 U1       000005 U2       000006 U3       000007 U4       000008 U5       000009 U6       00000A U7
 00000B U8       000011 OF       000014 1P       000015 LR       000016 00       000017 01       000018 02
 00002A 20       00002B 21       00007A L0       000085 H0       000086 H1       000087 H2       000088 H3
 000089 H4       00008A H5       00008B H6       00008C H7       00008D H8       00008E H9
000127  IDENTA        00012E  NAME          000151  ADDR1         000174  IDENTB        00017B  ADDR2
00019E  GENDER        00019F  PHONE         0001A5  BDATE         0001AA  MAJOR         0001AD  Z5
0001B0  B40           0001D8  CACNT         0001DA  CBCNT         0001DC  PREVA         0001E3  MISSB
0001EA  KEYH          0001F1  ADDCNT

The table gives the offset address (in hexadecimal) for all the Indicators and Fields used in the program.  Adding the address to the contents of Register 3 yields the absolute location in the dump to find the Indicator or Field contents at the time of the dump.

H0 Analysis

Of particular interest is H0, which is always located at x'85'.  If H0 is on, there is a table (the H0 analysis table) that may give additional information about the abend.  The contents of this table are found by adding Register 3 to x'11C', x'120', x'121', and x'122'.  Obviously the last three are adjacent single byte fields, so it is really only necessary to compute the first address.  The first address, if applicable, points to either an Input Output Request Block (IORB) or a Define The File (DTF) table.  The possible meanings that can be ascribed to the three reason codes are:

Condition that turned H0 on x'11C' x'120' x'121' x'122'
Initialized on or turned on by programmer N/A 00 00 00
Invalid chaining request N/A 02 N/A N/A
Undefined record type IORB 10 N/A N/A
Collating sequence error (matching records) N/A 04 N/A N/A
Record sequence error   N/A 08 N/A N/A
DAM (record not found) DTF N/A 80 N/A
DAM (data check) DTF N/A 40 N/A
DAM (wrong length record) DTF N/A 20 N/A
ISAM (invalid key length) IORB N/A N/A FF
ISAM (DASD error) DTF N/A N/A 80
ISAM (wrong length record) DTF N/A N/A 40
ISAM (illegal End Of File within limits) DTF N/A N/A 20
ISAM Load (prime data area full) DTF N/A N/A 20
ISAM Load (master index full) DTF N/A N/A 08
ISAM (duplicate record) DTF N/A N/A 04
ISAM Load (sequence error) DTF N/A N/A 02
ISAM Load (overflow area full) DTF N/A N/A 02
ISAM (no record found) DTF N/A N/A 10
ISAM Load (cylinder index full) DTF N/A N/A 10
ISAM Retrieve (illegal ID specified) DTF N/A N/A 08
ISAM Retrieve (record retrieved from overflow area) DTF N/A N/A 01

 Input/Output Request Blocks

The address listed in the Memory Map for Input Output Request Blocks Pointer, when adjusted by the addition of the contents of Register 3, points to a table of Input/Output information about the files defined in the RPG program which abended.  Each thirty-two byte entry in the table has the following format:

Displacement Contents
 0 address of record buffer
 4 address of parameter list for DAM or ISAM
 8 record length
10 line counter value
12 line counter info (x'11' = line counter present, x'EE' error in line counter routine
13 file number
14 action type (x'00' = read, x'02' = write, x'04' = stacker select
15 skip before or stacker number
16 space before
17 skip after
18 space after
19 overflow or end of file switch (x'00' = off, x'11' = printer overflow, x'22' end of file or end of extents, x'33' end of ISFMS limits
20 overflow switch two
21 sense overflow
22 ISAM with limits
23 first pass switch
24 file type
25 stacker select codes for device assigned to the file
27 record read from ISAM file (x'11' = record read, x'00' = record not read)
28 SETL switch (x'FF' = SETL or SETFL have been executed, x'00' = ESETL or ENDFL have been executed
29 ISAM key length
30 ISAM key location within data record

Table Information

When tables are used, the table names can be found in the field-names section of the Symbol Table.  Each table name will have an associated hexadecimal address.  By adjusting this address by the addition of the contents of Register 3, the table holding area can be found.  Initially, this holding area specifies the contents of the first table entry.  After a table LOKUP operation, the holding area will contain the contents of the last table entry found.  

The actual table in core can be found by use of a sixteen byte table linkage field.  The table linkage field is found by subtracting x'10' from the address of the table holding area.  The starting address of the table data is located in bytes five through eight of the table linkage field.  Bytes nine through twelve contain the address of the byte following the table.  The work address is found in bytes thirteen through sixteen.  Initially, this address contains hexadecimal zeros, but after a table LOKUP operation it contains the address of the last table element found.

Although not an exhaustive treatment of RPG dump analysis, this should be enough information to steer you to solving the majority of program problems.

Return to Site Home Page 

This page was last updated on January 17, 2015.