Wednesday, May 25, 2016

Debug views finding your favorite

debug views of various compile commands

How many of us have considered the different types of debug views that are available with the create (compile) program and module commands? We may have customized the create commands when installing a new release or, if we are using PDM, created our own customized PDM option for the create command. After that we get lazy, and this includes me, and we just leave the parameters the way they are without bothering to check what the various options do. By doing this we miss out on some very useful features that would make our use of debug easier.

In this post I am just going to cover the following create commands and what the different debug views show:

  • CRTBNDRPG - Create bound RPG program
  • CRTRPGMOD - Create RPG modules
  • CRTSQLRPGI - Create SQL ILE RPG object
  • CRTBNDCL - Create bound CL program
  • CRTCLMOD - Create CL module

The debug view parameter is not found in the CRTRPGPGM and CRTCLPGM commands. If you are still using those you owe it to your career to starting using modern RPG and CL. The parameter is available in the ILE Cobol and ILE ANSI C create commands too, but in my opinion why would you choose to use either of those languages when you can use modern RPG?

When the debug view parameter of the create commands is combined with the values in the options, either in the create command's option parameter or in RPG in the option parameter of the Control Options (CTL-OPT) or Header (Control) specifications, you can get some very interesting and useful views when debugging.

Examples of the option keywords in the CTL-OPT and H-spec in RPG would be:

//free format definition
ctl-opt option(*srcstmt:*showcpy:*expdds) ;

.....HKeywords++++++++++++++++++++++++++
      * Fixed format definition
     H option(*srcstmt:*showcpy:*expdds)

If you put contrary values in the Option parameter of the CRTBNDRPG and CRTRPGMOD commands they will take precedence over what is in the source code.

Let me start with the RPG create commands. The actions of the option and debug view parameters are the same for both the CRTBNDRPG and CRTRPGMOD commands.

 

RPG DBGVIEW(*STMT)

When you debug a RPG program/module compiled with DBGVIEW(*STMT) the source is not displayed. This brings back memories of debugging RPGIII code, so I do not use this debug view, and recommend that neither do you.

 

RPG OPTION(*SRCSTMT) DBGVIEW(*SOURCE),
    OPTION(*NOSRCSTMT) DBGVIEW(*SOURCE),
    OPTION(*SRCSTMT) DBGVIEW(*ALL),
    OPTION(*NOSRCSTMT) DBGVIEW(*ALL)

Despite the differences described in IBM's documentation when I start debug (STRDBG) the same code is displayed for all of the combinations listed above.

                     Display Module Source 

Program:  TESTRPG    Library:  MYLIB    Module:  TESTRPG
     1  **free
     2  dcl-f TESTFILE ;
     3
     4  /copy devsrc,copybook1
     5
     6  read TESTFILE ;
     7
     8  *inlr = *on ;

 

RPG OPTION(*SRCSTMT) DBGVIEW(*LIST)

This pretty much looks like the previous example. The only difference is that I now have the source sequence number shown next to the RPG code.

 1           *MODULE ENTRY AND MAIN PROCEDURE ENTRY
 2     000100 **free
 3     000200 dcl-f TESTFILE ;
 4     000300
 5     000400 /copy devsrc,copybook1
 6     000500
 7     000600 read TESTFILE ;
 8     000700
 9     000800 *inlr = *on ;
10           *MAIN PROCEDURE EXIT

 

RPG OPTION(*SHOWCPY *EXPDDS *SRCSTMT) DBGVIEW(*LIST)

By using the Show Copy Members (*SHOWCPY) and the Expand DDS (*EXPDDS) the debug code includes the data from the /COPY member and the input specifications for the file. As I have the Source Statement (*SRCSTMT) option notice that the contents of the copy book, line 6, has its own source sequence number, and the same is true for the input specifications, lines 8 – 10.

 1           *MODULE ENTRY AND MAIN PROCEDURE ENTRY
 2     000100 **free
 3     000200 dcl-f TESTFILE ;
 4     000300
 5     000400 /copy devsrc,copybook1
 6     000100+ //COPYBOOK1
 7     000500
 8     000001=     ITESTFILER
 9     000002=     I                             A    1   10  F001
10     000003=     I                             A   11   15  F002
11     000600 read TESTFILE ;
12     000700
13     000800 *inlr = *on ;
14           *MAIN PROCEDURE EXIT

 

RPG OPTION(*SHOWCPY *EXPDDS *NOSRCSTMT) DBGVIEW(*LIST)

The only difference between this and the previous example is that in the one I am not using the Source Statement (*NOSRCSTMT) option. The sequence numbers are sequential and do not match the numbers in the source code.

 1           *MODULE ENTRY AND MAIN PROCEDURE ENTRY
 2          1 **free
 3          2 dcl-f TESTFILE ;
 4          3
 5          4 /copy devsrc,copybook1
 6          5+ //COPYBOOK1
 7          6
 8          7=     ITESTFILER
 9          8=     I                             A    1   10  F001
10          9=     I                             A   11   15  F002
11         10 read TESTFILE ;
12         11
13         12 *inlr = *on ;
14           *MAIN PROCEDURE EXIT

 

CRTSQLRPGI DBGVIEW(*SOURCE)

When using the CRTSQLRPGI there are only two choices for the debug view:

  1. *NONE
  2. *SOURCE

If I use the source parameter my debug view looks like the source view for the RPG program/procedure.

 1  **free
 2  dcl-ds InputDs extname('TESTFILE') qualified ;
 3  end-ds ;
 4
 5  /copy devsrc,copybook1
 6
 7  exec sql DECLARE C0 CURSOR FOR
 8            SELECT * FROM TESTFILE FOR READ ONLY ;
 9
10  exec sql OPEN C0 ;
11
12  exec sql FETCH C0 INTO :InputDs ;
13
14  exec sql CLOSE C0 ;
15  *inlr = *on ;

 

I have a very simple CL program, that has a file and a include, that I will be using for my examples:

  PGM

  DCLF       FILE(TESTFILE)

  INCLUDE    SRCMBR(COPYBOOK2) SRCFILE(MYLIB/DEVSRC)
 
  RCVF

  ENDPGM

Both the CL create commands, CRTBNDCL CRTCLMOD, act the same way with the debug view.

 

CL DBGVIEW(*SOURCE),
   DBGVIEW(*ALL)

I think I have found a bug in the CL compiler. If I compile my program with the debug view of source or all, and then STRDBG I get a message that says "Source file has changed", which goes on to explain:

The file DEVSRC in library MYLIB with member TESTCLPGM has changed after the view was created. The source for the view may be out of date.

Which is utter balderdash as the program was compiled seconds before.

If I comment out the INCLUDE command I can view the source code in debug:

 1               PGM
 2
 3               DCLF       FILE(TESTFILE)
 4
 5             /*INCLUDE    SRCMBR(COPYBOOK2) SRCFILE(MYLIB/DEVSRC)*/
 6
 7               RCVF
 8
 9               ENDPGM

 

CL DBGVIEW(*LIST)

There is no such problem with the list debug view. It includes the code from the external source member and the fields in the file.

It even goes further and gives the compiler options in a "heading" section, reminiscent of the output from the RTVCLSRC command.

 1   5770SS1 V7R2M0  140418                  Control Language
 2   Program . . . . . . . . . . . . . . . . . . . :   TESTCLPGM
 3     Library . . . . . . . . . . . . . . . . . . :     MYLIB
 4   Source file . . . . . . . . . . . . . . . . . :   DEVSRC
 5     Library . . . . . . . . . . . . . . . . . . :     MYLIB
 6   Source member name  . . . . . . . . . . . . . :   TESTCLPGM
 7   Source printing options . . . . . . . . . . . :   *XREF
 8   User profile  . . . . . . . . . . . . . . . . :   *USER
 9   Program logging . . . . . . . . . . . . . . . :   *YES
10   Allow RTVCLSRC command  . . . . . . . . . . . :   *YES
11   Default activation group  . . . . . . . . . . :   *YES
12   Replace program . . . . . . . . . . . . . . . :   *YES
13   Target release  . . . . . . . . . . . . . . . :   V7R2M0
14   Authority . . . . . . . . . . . . . . . . . . :   *LIBCRTAUT
15   Sort sequence . . . . . . . . . . . . . . . . :   *HEX
16   Language identifier . . . . . . . . . . . . . :   *JOBRUN
17   Text  . . . . . . . . . . . . . . . . . . . . :
18   Optimization  . . . . . . . . . . . . . . . . :   *NONE
19   Debugging view  . . . . . . . . . . . . . . . :   *LIST
20   Debug encryption key  . . . . . . . . . . . . :   *NONE
21   Enable performance collection . . . . . . . . :   *PEP
22   Storage model . . . . . . . . . . . . . . . . :   *SNGLVL
23   Compiler  . . . . . . . . . . . . . . . . . . :   IBM Contro
24                                        Control Language Source
25   SEQNBR  *...+... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 .
26      100-              PGM
27      200-
28      300-              DCLF       FILE(TESTFILE)
29
30           QUALIFIED FILE NAME - MYLIB/TESTFILE
31
32              RECORD FORMAT NAME - TESTFILER
33
34                CL VARIABLE               TYPE     LENGTH     PRECISION
35                 &F001                    *CHAR      10
36                 &F002                    *CHAR      10
37
38      400-
39      500- /* START INCLUDE SRCMBR(COPYBOOK2)  SRCFILE(MYLIB/DEVSRC)
40      600- /*COPYBOOK2*/
41      700- /* END   INCLUDE SRCMBR(COPYBOOK2)  SRCFILE(MYLIB/DEVSRC)
42      800-
43      900-              RCVF
44     1000-
45     1100-              ENDPGM
46                                 * * * * *   E N D   O F   S O U R C E
47                                            Cross Reference
48   Declared Variables
49   Name                        Defined     Type            Length
50   &F001                          300      *CHAR              10
51   &F002                          300      *CHAR              10
52  * CPD0791 00  No labels used in program.
53                       * * * * *   E N D   O F   C R O S S   R E F E R E
54                                   * * * * *   E N D   O F   C O M P I L

 

I must admit having researched this subject I have changed my compile options to use the list debug view. If ever the source member is ever lost the list debug view can be used to recreate it.

 

You can learn more about this from the IBM website:

 

This article was written for IBM i 7.2, and should work for some earlier releases too.

15 comments:

  1. I always recommend the use of *ALL. The source view is useful when you just want to step through the actual coded logic. The list view is useful when I want to see external expansions etc. and of course if I lose the code! By using *ALL I always have access to both!

    ReplyDelete
    Replies
    1. Back in the bad old days when we had to take a printout of the compilation listing, we avoided *all. If the source was lost, we always had to printout to punch the whole code once again.

      These days hard disk is plenty, and we can afford *all, unless we are going thru it line by line, as you mentioned.

      Delete
  2. Hi!, nice article!

    Just a question.
    Is there any way to debug COPY in ILERPG with SQL embedded?
    I cannot find a good option in CRTSQLRPGI command.

    Thanks!

    ReplyDelete
    Replies
    1. I forgot to add info.
      I know that if you are using the STRDBG command, it works (F15 and choose view).

      But, I'm an user of Rational developer for I (version 9.5), and I can't find the way to do the same here.
      I cannot see the code that comes from COPY, or, even, the SQL code (I'm not very interested on it, but, it's something I can do with STRDBG, but not with RDI)


      Thanks!

      Delete
    2. Yes you can, if you compile with *listing or *all option. Inside the editor, try "Switch View" to switch to *listing view.

      Actually I find the view more pleasing to my eyes than that of STRDBG

      Delete
  3. A comment hyperlink took to me this page.. so, this means that we cant hardcode DBGVIEW(*SOURCE) in rpgle.. and we need to add it by taking 14 while compiling the source?

    ReplyDelete
    Replies
    1. You can have DBGVIEW(*SOURCE) in your RPGLE source code. I am sure I give example in other posts with it there.

      Delete
  4. Hi Simon, sorry,
    1) i couldnt find an example where DBGVIEW(*LIST) or DBGVIEW(*SOURCE) is hardcoded in RPGLE free.
    2) When i browsed, i found an option to be set for SQLRPGLE only.
    exec sql set option compileopt = DBGVIEW(*LIST);
    3) In your website, i came across the following.
    we could set an user defined option in PDM.

    Please advise if there is a way to hardcode !

    ReplyDelete
    Replies
    1. I misspoke. There is NOT a DBGVIEW for RPGLE. Therefore, there is no way to hardcode a debug view into the source.

      The only ways I can think to do it is to use a PDM user defined option when compiling, or to change the CRT command itself.

      Delete
  5. I've never considered the many options that you showed. I'm going to play with these on Monday. Thanks for the read

    ReplyDelete
  6. For CRTRPGPGM, CRTCLPGM and CRTCBLPGM, you can compile with OPTION(*LSTDBG) or OPTION(*SRCDBG). Then, when debugging, you can use STRDBG OPMSRC(*YES) to debug using the listing "view" or source "view".

    ReplyDelete
  7. Note that while DBGVIEW(*ALL) _initially_ shows the source view, it's not true that it's the same as DBGVIEW(*SOURCE) for CRTBNDxxx or CRTxxxMOD. DBGVIEW(*ALL) gives both the source view and the listing view, and for the RPG commands, it also gives the *COPY view.

    For CRTSQLxxxI, DBGVIEW(*SOURCE) gives you the source view for the SQL source, and the DBGVIEW(*ALL) view for the generated source for the target language.

    ReplyDelete
  8. Simon, thanks for sharing it’s a great white paper.

    “When you debug a RPG program/module compiled with DBGVIEW(*STMT) the source is not displayed. This brings back memories of debugging RPGIII code”

    It does and RPGII Great comment..Again, thanks for sharing and giving us another learning moment..

    ReplyDelete
  9. very, very good!!

    ReplyDelete
  10. Wonderful to read through!!

    ReplyDelete

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.