Thursday, June 13, 2019

New subfields added to Program Status Data Structure

two new subfields added to the new program status data structure

The latest Technology Refresh for IBM i 7.3, TR6, has seen two new subfields added to RPG's Program Data Structure. This data strucutre provides me with a wealth information about the status of the program while it is running, and when it errors.

I always add the Program Status Data Structure, PSDS, to all of my RPG programs. I can dump the program and learn a lot of what happened from the information contains within the PSDS.

Rather than manually entering the same data structure into every program, I have my PSDS in a member I just copy, or include, it into the source members of others.

Below is my definition for the PSDS. If you are creating your own you can give the data structure and subfields whatever names you like.

dcl-ds Pgm psds qualified ;
  Proc char(10) ;             // Module or main procedure name
  StsCde zoned(5) ;           // Status code
  PrvStsCde zoned(5) ;        // Previous status
  SrcLineNbr char(8) ;        // Source line number
  Routine char(8) ;           // Name of the RPG routine
  Parms zoned(3) ;            // Number of parms passed to program
  ExceptionType char(3) ;     // Exception type
  ExceptionNbr char(4) ;      // Exception number
  Exception char(7) samepos(ExceptionType) ;
  Reserved1 char(4) ;         // Reserved
  MsgWrkArea char(30) ;       // Message work area
  PgmLib char(10) ;           // Program library
  ExceptionData char(80) ;    // Retrieved exception data
  Rnx9001Exception char(4) ;  // Id of exception that caused RNX9001
  LastFile1 char(10) ;        // Last file operation occurred on
  Unused1 char(6) ;           // Unused
  DteEntered char(8) ;        // Date entered system
  StrDteCentury zoned(2) ;    // Century of job started date
  LastFile2 char(8) ;         // Last file operation occurred on
  LastFileSts char(35) ;      // Last file used status information
  JobName char(10) ;          // Job name
  JobUser char(10) ;          // Job user
  JobNbr zoned(6) ;           // Job number
  StrDte zoned(6) ;           // Job started date
  PgmDte zoned(6) ;           // Date of program running
  PgmTime zoned(6) ;          // Time of program running
  CompileDte char(6) ;        // Date program was compiled
  CompileTime char(6) ;       // Time program was compiled
  CompilerLevel char(4) ;     // Level of compiler
  SrcFile char(10) ;          // Source file name
  SrcLib char(10) ;           // Source file library
  SrcMbr char(10) ;           // Source member name
  ProcPgm char(10) ;          // Program containing procedure
  ProcMod char(10) ;          // Module containing procedure
  SrcLineNbrBin bindec(2) ;   // Source line number as binary
  LastFileStsBin bindec(2) ;  // Source id matching positions 228-235
  User char(10) ;             // Current user
  ExtErrCode int(10) ;        // External error code
  IntoElements int(20) ;      // Elements set by XML-INTO or DATA-INTO (7.3)
  InternalJobId char(16) ;    // Internal job id (7.3 TR6)
  SysName char(8) ;           // System name (7.3 TR6)
end-ds ;

Two things to note are:

  1. As the data structure has been written in totally free format RPG I have to start the source member with **FREE. If I don't do so when the member is copied into the other source member by the RPG compiler it copies the member starting in the seventh column of the source member.
  2. I have used the SAMEPOS keyword to combine the Exception Type and Exception Number subfields.

The two new subfields are the last two in the data structure. I have to admit I am unsure what the "Internal job id" is.

Just to give you a glimpse of the information I can see in the PSDS I wrote this program of just three lines:

01  **free
02  /include cpysrc,rpg_psds

03  *inlr = *on ;

Lines 2: I have used the /INCLUDE compiler directive to copy the contents of the PSDS into this program.

After compiling the program I started debug and put added a break point on the last line of the program. I see the following in the PSDS:

EVAL pgm
PGM.STSCDE = 00000.
PGM.SRCLINENBR = '00000000'
PGM.PARMS = 000.
PGM.EXCEPTION = '       '
PGM.RESERVED1 = '0000'
PGM.MSGWRKAREA = '                              '
  1 '                                                            '
 61 '                    '
PGM.LASTFILE1 = '          '
PGM.UNUSED1 = '      '
PGM.DTEENTERED = '06122019'
PGM.LASTFILE2 = '        '
PGM.LASTFILESTS = '                                   '
PGM.JOBNBR = 526346.
PGM.STRDTE = 061219.
PGM.PGMDTE = 061219.
PGM.PGMTIME = 032844.
PGM.INTERNALJOBID = ' ? ? ?" sM´Þmǵ?'


As I work in a multiple partition world being able to retrieve the System Name is going to help me to be able to condition code depending upon which partition the program is running on, without retrieving the network name using a CL command.


You can learn more about the Program Status Data Structure from the IBM website here.


This article was written for IBM i 7.4 and 7.3 TR6.


  1. Simon. Love your work. I learn a lot. What is your opinion on using an externally described PF for the SDS definition? I have been using the same one for decades.

    1. For many years (possibly decades too), starting with RPG3, I used a file as you described.

      My opinion is if you prefer to use a file that is fine. If you want to make a source member and /INCLUDE it into your source that is fine too.

      Use whichever one you feel comfortable with.


To prevent "comment spam" all comments are moderated.
Learn about this website's comments policy here.

Some people have reported that they cannot post a comment using certain computers and browsers. If this is you feel free to use the Contact Form to send me the comment and I will post it for you, please include the title of the post so I know which one to post the comment to.