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:
- *NONE
- *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.
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!
ReplyDeleteBack 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.
DeleteThese days hard disk is plenty, and we can afford *all, unless we are going thru it line by line, as you mentioned.
Hi!, nice article!
ReplyDeleteJust a question.
Is there any way to debug COPY in ILERPG with SQL embedded?
I cannot find a good option in CRTSQLRPGI command.
Thanks!
I forgot to add info.
DeleteI 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!
Yes you can, if you compile with *listing or *all option. Inside the editor, try "Switch View" to switch to *listing view.
DeleteActually I find the view more pleasing to my eyes than that of STRDBG
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?
ReplyDeleteYou can have DBGVIEW(*SOURCE) in your RPGLE source code. I am sure I give example in other posts with it there.
DeleteHi Simon, sorry,
ReplyDelete1) 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 !
I misspoke. There is NOT a DBGVIEW for RPGLE. Therefore, there is no way to hardcode a debug view into the source.
DeleteThe 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.
I've never considered the many options that you showed. I'm going to play with these on Monday. Thanks for the read
ReplyDeleteFor 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".
ReplyDeleteNote 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.
ReplyDeleteFor 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.
Simon, thanks for sharing it’s a great white paper.
ReplyDelete“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..
very, very good!!
ReplyDeleteWonderful to read through!!
ReplyDelete