Quick sample debugging session with PL/I
This section demonstrates some of the basic interactive debugging features of Code Debug TSO, using the sample PL/I program TRIMAINP, which calls TRITSTP and TRIRPTP. This quick overview shows you how to do the following:
- Prepare the programs
- Start an interactive debugging session
- Step through code
- Trace statements
- Count statements
- Set breakpoints
- View and modify data values.
Preparing the programs
The source for the sample programs TRIMAINP, TRITSTP, TRIRPTP, and TRIDATA (the data set containing the data) is provided in the SLXTSAMP library. The common load module, test data, DDIO data set, and file list libraries should have already been created and/or verified by your site installer. Contact your installer for the names of these data sets and libraries.
If these data sets and libraries were not created, you must compile and link edit the programs using the BMC AMI Common Shared Services (CSS) PL/I language processor. You must also specify the appropriate load module on the Setup screen.
Option 1 on the Code Debug TSO Primary Menu can be used to compile and link edit the programs. See to Preparing Your Programs if you require assistance.
When you are ready to start the session, do the steps listed in Starting the Debugging Session.
Starting the debugging session
- Type PLI64 in the Profile field on the Code Debug TSO Primary Menu to set up a profile for the session. Code Debug displays the Profile screen, and prompts you to enter a description for the new profile. Enter PLI TRIMAINP in the description area and press the END key. The Primary Menu is redisplayed.
- Type 2 (TSO) in the command line on the Primary Menu and press Enter. The Environments Menu is displayed if this is your first time invoking a Code Debug TSO debugging session. Otherwise, the last environment test screen you used is displayed. To access the Environments Menu, type SETUP in the command line of the displayed environment test screen. Then select option 0 on the Test Setup Menu to display the Environments Menu.
- Type 1 (STANDARD) on the Environments Menu.
- Press Enter.
- Type SETUP on the standard test screen.
- Type 1 (LOADLIBS) on the Setup Menu.
- On the Load Module Libraries screen, enter the name of the application load library that contains the TRIMAINP load module (optional).
- Press Enter.
- Type 2 (DDIO) on the Setup Menu.
- On the DDIO Files screen, you may enter the DDIO data set name that contains the source listing member of TRIMAINP. In addition to the original DDIO data set name, you may also specify a Shared Directory data set name and/or an LP database data set name.
- Press Enter.
- Enter END or press PF3 to return to the standard environment test screen.
Specify the name of the program and the name of the file list or the JCL containing the names of the files required by your program. Complete the screen as shown in the following figure.
Standard Test Screen
COMMAND ===>
COMMANDS: SEtup (Display Setup Menu)
PROFile (Display Profile Selection)
TEST SELECTION CRITERIA:
Program ===> TRIMAINP
Entry Point ===>
Load Module ===>
Initial Script ===>
Post Script ===>
PARM ( Caps = YES ) ===>
File List/JCL Member ===>
Preview Files? ===> NO
Code Coverage Test? ===> NO (YES, NO, TDO) SYSTEM FLOW? ===> NO
Is This a DB2 Test? ===> NO Plan ===> System ===>
Press ENTER to process or enter END command to terminate
Press Enter to begin the Code Debug TSO debugging session. The message area contains the lines Allocating Code Debug TSO Data sets, then Allocating User Data sets. On a blank screen, the message Entering Code Debug TSO Test Environment appears.
Code Debug TSO processes the file list, allocates the necessary data sets, loads the program TRIMAINP, and displays the PL/I source listing. The message BEFORE BREAKPOINT ENCOUNTERED is displayed and the execution arrow (=====>) points to the PROCEDURE statement. This means that TRIMAINP stopped before beginning execution of the program. Also, a left/right scroll indicator (e.g., -- Before TRIMINP1 <>) appears on the execution status line. A double arrow indicates that scrolling is allowed both left and right. An example of the source display is shown in the following figure.
TRIMAINP Program in the Source Display
COMMAND ===> SCROLL===> CSR
BEFORE BREAKPOINT ENCOUNTERED
** END **
------ ------------------------------------------- Before TRIMINP1/AMODE 31 <>
=====> B TRIMAINP: PROC OPTIONS(MAIN);
------
000002 DCL INFILE INPUT RECORD FILE;
000003 DCL IN_REC CHAR(80);
------ /* */
------ /* */
------ /* DECLARE EXTERNAL ENTRY PROGRAMS */
------ /* */
------ /* */
------
000004 DCL TRITSTP EXTERNAL ENTRY;
000005 DCL TRIRPTP EXTERNAL ENTRY;
000006 DCL ADDR BUILTIN;
------
000007 DCL 1 N_N_C_TABLE,
Stepping through the code
The first time the program is displayed, you will want to see how the program works by stepping through one statement at a time. Press PF9 (GO 1) to execute statements one-by-one. As shown in the following figure, program execution stops on statement 12, as indicated by the execution arrow.
Stepping Through Code
COMMAND ===> SCROLL===> CSR
PROGRAM: TRIMINP1 MODULE: TRIMAINP COMP DATE: 08/07/1995 COMP TIME:11:38:50
** END **
------ --------------------------------------- Before TRIMINP1:12/AMODE 31 <>
=====> ON ENDFILE(INFILE)
------ BEGIN;
000013 OUT_OF_RECS = ‘1’B;
000014 END;
Press PF9 (GO 1) again. Program execution stops on statement 15, and so forth as you continue to press PF9.
Enter RETEST on the command line to obtain a fresh copy of the source.
Analyzing program logic
When you are not sure what the program is doing, you can trace the logic, highlighting each statement as it is executed with the TRACE command. Following program execution under live conditions speeds comprehension. Enter the following on the primary command line to control the tracing speed:
Then enter the following on the command line to trace all statements executed:
Each statement that is executed is highlighted. When the default of 25 statements has been reached, program execution pauses and the following message is displayed:
To look at the output from the TRACE command enter LOG on the command line to look at the session log. The session log shows which statements were executed during the trace. See the following figure.
Code Debug TSO Session Log Showing Statement Execution Tracing
COMMAND ===> SCROLL===> CSR
PROGRAM: TRIMINP1 MODULE: TRIMAINP COMP DATE: 01/17/1995 COMP TIME:11:38:50
----------------------------------------------- Before TRIMINP1:29/AMODE 31 ->
Trace TRIMINP1:12 IN TRIMAINP
Trace TRIMINP1:15 IN TRIMAINP
Trace TRIMINP1:20 IN INIT_PARA
Trace TRIMINP1:21 IN INIT_PARA
------------------------------- TRIMINP1 KEPT ITEMS ----------------------------
0 OCCURS
----+
000007 10 N_CNTR > ????? INVALID ZONED
--------------------------------------------------------------------------------
Trace TRIMINP1:22 IN INIT_PARA
Trace TRIMINP1:23 IN INIT_PARA
------------------------------- TRIMINP1 KEPT ITEMS ----------------------------
-
000009 OUT_OF_RECS > 0 B
--------------------------------------------------------------------------------
Trace TRIMINP1:24 IN INIT_PARA
Trace TRIMINP1:16 IN TRIMAINP
------------------------------- TRIMINP1 KEPT ITEMS ---------------------------
Notice that the arrow on the status line indicates that you can scroll to the right.
Another way to analyze program logic is to count the number of times a statement is executed. The COUNT command is used for this purpose. For this demonstration we will count the number of times each statement is executed. First enter the following on the command line to end the tracing mode.
Then, enter:
When the program completes execution, you can scroll back through the program to look at the results of the COUNT command. The COUNT command gives immediate results by displaying a 7-digit counter field in columns 74 through 80, as shown in the following figure.
Result of Using the Count Command
000026 READ FILE(INFILE) SET(IN_REC_PTR); 0000012
000027 IF ¨OUT_OF_RECS THEN DO; 0000012
000028 TRIANGLE_TYPE = 0; 0000011
000029 CALL TRITSTP (WORK_REC, 0000011
------ TRIANGLE_TYPE);
000030 TX = TRIANGLE_TYPE; 0000011
000031 N_CNTR(TX) = N_CNTR(TX) + 1; 0000011
000032 END; 0000012
000033 END ANALYZE_NEXT_REC; 0000012
------
000034 ENDING_PARA: PROC; 0000001
000035 CLOSE FILE(INFILE); 0000001
Enter RETEST on the command line.
Setting breakpoints
When testing a program, you may want to stop program execution to see the value of a variable at a particular statement, check the operands in a calculation, inspect a record that may be causing a problem, and so on. With breakpoint commands, you can stop program execution before or after a statement, procedure, module, and so forth.
Breakpoint commands can be entered on the primary command line or in the line command area. For this example, move the cursor to statement number 25 at the ANALYZE_NEXT_REC procedure, then type over the statement number with the B (Before) line command. When you press Enter, a B appears in column 9 on statement 25, indicating that a before breakpoint has been set. See the following figure. This breakpoint causes program execution to pause before executing the ANALYZE_NEXT_REC procedure.
Result of Entering a Before Breakpoint
------
000025 B ANALYZE_NEXT_REC: PROC;
000026 READ FILE(INFILE) SET(IN_REC_PTR);
000027 IF ¨OUT_OF_RECS THEN DO;
000028 TRIANGLE_TYPE = 0;
Press PF12 or enter GO to execute TRIMAINP until the breakpoint is reached. The program stops at statement 25, where the execution arrow is pointing. The execution status field on the fourth line also shows that execution is paused at Before TRIMINP1:25 as shown in the following figure.
Program Stopped at Before Breakpoint on Statement 25
COMMAND ===> SCROLL===> CSR
BEFORE BREAKPOINT ENCOUNTERED
** END **
------ -------------------------------------- Before TRIMINP1:25/AMODE 31 <>
000024 END INIT_PARA;
------
=====> B ANALYZE_NEXT_REC: PROC;
000026 READ FILE(INFILE) SET(IN_REC_PTR);
000027 IF ¨OUT_OF_RECS THEN DO;
Displaying data values
Whenever program execution halts, Code Debug TSO automatically displays the value of data items referenced by the current execution line. These automatic keeps are displayed in a window at the top of the screen. Each time the program stops, a new set of variables and their values are displayed.
Also, any time you stop program execution, you can use the KEEP command to continuously display the contents of any number of variables as your program executes.
For this example, you will use the KEEP command and watch the values of WORK_REC and TRIANGLE_TYPE to see if the calculations are being performed correctly. Move the cursor to statement 11 (WORK_REC) and enter KE (Keep Element) so that you can view the contents of each element. Then move the cursor to statement 10 (TRIANGLE_TYPE) and enter K (Keep). The Keep window at the top of the screen in the following figure has been expanded so that all the kept items can be displayed. See to the SET command in the Command-and-syntax-reference for additional information on setting window size. The K in column 9 differentiates an explicit keep from an automatic keep.
Displaying the Variables WORK_REC and TRIANGLE_TYPE
COMMAND ===> SCROLL===> CSR
PROGRAM: TRIMINP1 MODULE: TRIMAINP COMP DATE: 08/07/1995 COMP TIME: 11:38:50
IN_REC @NO ADDR
000011 K 05 SIDE_A > NO ADDR
IN_REC @NO ADDR
000011 K 05 SIDE_B > NO ADDR
IN_REC @NO ADDR
000011 K 05 SIDE_C > NO ADDR
000010 K TRIANGLE_TYPE > ?? INVALID PACKED
------ -------------------------------------- Before TRIMINP1:25/AMODE 31 <>
------ /* DECLARE EXTERNAL ENTRY PROGRAMS */
------ /* */
------ /* */
Press PF12 (GO) to execute TRIMAINP. As shown in the following figure, the B (BEFORE) breakpoint at statement 25 stopped execution before executing the ANALYZE_NEXT_REC procedure. You can see that record 345 was read into WORK_REC and TRIANGLE_TYPE and contains a value of 3 indicating that the value 345 is equal to a scalene (type 3) triangle.
Data Displayed in the Keep Window
COMMAND ===> SCROLL===> CSR
BEFORE BREAKPOINT ENCOUNTERED
IN_REC @00221BC0
000011 K 05 SIDE_A > 3 ZONED
IN_REC @00221BC0
000011 K 05 SIDE_B > 4 ZONED
IN_REC @00221BC0
000011 K 05 SIDE_C > 5 ZONED
000010 K TRIANGLE_TYPE > +3 PACKED
------ -------------------------------------- Before TRIMINP1:25/AMODE 31 <>
------
=====> B ANALYZE_NEXT_REC: PROC;
000026 READ FILE(INFILE) SET(IN_REC_PTR);
000027 IF ¨OUT_OF_RECS THEN DO;
Press PF12 again. The next record 789 is read in the second time through the loop. WORK_REC is updated to reflect the change and TRIANGLE_TYPE remains the same because 789 equals a type 3 triangle. See to the following figure.
Seeing Data Change in the Keep Window
COMMAND ===> SCROLL===> CSR
BEFORE BREAKPOINT ENCOUNTERED
IN_REC @00221C10
000011 K 05 SIDE_A > 7 ZONED
IN_REC @00221C10
000011 K 05 SIDE_B > 8 ZONED
IN_REC @00221C10
000011 K 05 SIDE_C > 9 ZONED
000010 K TRIANGLE_TYPE > +3 PACKED
------ -------------------------------------- Before TRIMINP1:25/AMODE 31 <>
If you continue pressing PF12, you will see the value of TRIANGLE_TYPE change when the value of WORK_REC changes to a different type of triangle.
Debugging subroutines
Statement 29 shows that the program TRIMAINP calls TRITSTP and passes parameters WORK_REC and TRIANGLE-TYPE. In order to examine how TRITSTP is processing these parameters, you can set a breakpoint at the beginning of TRITSTP to gain control of the execution when the call is made. Enter the following command on the primary command line:
The colon (:) after the program name indicates that a module-level breakpoint is requested. Press PF12 (GO) to execute the program. Code Debug TSO pauses execution at the TRITSTP procedure as shown in the following figure Note the automatic keeps displayed in the Keep window.
Execution Stopped at the TRITSTP Procedure
COMMAND ===> SCROLL===> CSR
BEFORE BREAKPOINT ENCOUNTERED
---
000002 01 TST_REC > 124
TYPE_OF_TRIANGLE > +0 PACKED
** END **
------ ------------------------------------------- Before TRITSTP1/AMODE 31 <>
=====> B TRITSTP: PROC(TST_REC, TYPE_OF_TRIANGLE);
------
000002 DCL 1 TST_REC,