Controlling program execution
This section describes the Code Debug TSO commands that let you control program execution. Some of these commands, called breakpoint commands, are used to start and stop execution at any time or when a specified condition occurs. Breakpoint commands let you designate the location of the pause by statement number, label name, procedure name, or by the occurrence of a particular event. The other commands that control execution are used to specify the procedure to be displayed as the active procedure.
When program execution is paused, you can enter other Code Debug TSO debugging commands to examine program data, analyze and follow program logic, and many other debugging functions. Execution resumes when you enter GO or press PF12.
Execution is automatically stopped when an abend occurs. Code Debug TSO intercepts program abends and automatically pauses at the failing statement. Some abends can be corrected dynamically, and execution can be resumed without terminating the session.
Commands that control execution
The following are Code Debug TSO commands that control execution.
AFTER
Stops execution after the specified line of code is executed. An after module breakpoint is automatically set at the main procedure before the program begins executing. An after breakpoint is set on each RETURN or END procedure-name in the procedure when an AFTER module breakpoint is requested.
An after breakpoint set at a call to an external procedure stops after completing the call. An after breakpoint set on a call to an internal procedure stops before executing the first statement in the procedure.
AT
Sets breakpoints in a sourceless main or fetched procedure. Sourceless debugging and using the AT command are discussed in Debugging a Sourceless Program.
BEFORE
Stops execution before a specified line of code is executed. A before module breakpoint is automatically set at the main procedure before the program begins executing. A before breakpoint is set on the PROCEDURE and ENTRY statement in the procedure when a before module breakpoint is requested. You must set a before breakpoint at the beginning of a called procedure if you want to stop execution before the procedure executes.
COUNT
Counts the number of times a statement is executed. Optionally stops execution when a statement executes a specified number of times.
GO
Begins execution and resumes execution after a pause. Conditionally executes a specified number of statements or labels.
INTERCEPT
Loads the specified external procedure and sets a before and after module breakpoint at the PROCEDURE and END statements before the program begins executing.
ONETIME
Is functionally equivalent to a before breakpoint, stopping before a specified line of code is executed. However, the onetime breakpoint is removed automatically after it is encountered.
PAUSE
Pauses execution within a block of code that has been inserted.
PSEUDOSOURCE
Generates pseudo-assembler code for a program with no DDIO listing member. Using the PSEUDOSOURCE command is discussed in Creating Pseudo-Assembler Source.
RETEST
Reloads the procedure you are debugging and restarts the test session.
SKIP
Bypasses execution of source code, which can include bypassing a procedure.
SOURCE
Displays the specified external procedure and makes it the qualified procedure. Any subsequent Code Debug TSO commands that are entered are applied to the specified external procedure.
TRACE
Traces the flow of control as the program executes.
WHEN
Suspends execution when a specified condition occurs.
Entering program control commands
A simple way to enter a breakpoint command is to scroll to the source line where you want execution to pause, type the command in the line command area, and press Enter. You will see an indication of the breakpoint in column 9 on the Source screen.
To set a breakpoint at a specific location or occurrence of a specified event, enter the breakpoint command from the primary command line with a location operand or a condition for the stop. See to the Command-and-syntax-reference for the valid location operands and parameters for a command.
If the primary command line is too small to list breakpoints or to stack commands, enter the SET CMDSIZE command to expand the command line to up to three lines.
When you set a breakpoint on a line that has multiple statements, execution only stops at the first code statement on the line. You must use GO 1 to stop at every statement on the line. For example, the following figure shows a before breakpoint on statement 25 (STAKMNTH = MONTH_CODE). Although you cannot set a breakpoint on statement 26 (RECORD_CTR = RECORD_CTR +1), you can use GO 1 to stop at that statement.
Setting Breakpoints on Lines with Multiple Statements
COMMAND ===> SCROLL ===> CSR
BEFORE BREAKPOINT ENCOUNTERED
** END **
------ ------------------------------------------- Before MAINPLI1/AMODE 31 <>
=====> B CALC_VACATION: PROC:
000024 ALLOCATE STAKMNTH;
=====> B STAKMNTH = MONTH_CODE; RECORD_CTR = RECORD_CTR + 1;
000027 MONTH = SUBPXXXXONG(MONTH_CODE);
000028 R_EMP_NO = EMPLOYEE_NUMBER_WITH
When a statement continues across multiple lines, the breakpoint indicator is displayed on the line where the statement began.
To set a breakpoint on a statement that is preceded by a label, you must set the break-point next to the label. For example, in the following figure, the breakpoint is set on the label in order to stop execution at the assignment statement TOTAL_NET_PAY = TOTAL_CTR.
Setting a Breakpoint on a Label
COMMAND ===> SCROLL===> CSR
2 COMMAND(S) COMPLETED
** END **
------ ------------------------------------------- Before MAINPLI1/AMODE 31 <>
=====> END CALC_VACATION;
000067 B WRITE_TOTAL:
------ TOTAL_NET_PAY = TOATL_CTR;
000068 WRITE FILE (OUTLIST) FROM (FINAL_LINES);
000069 CLOSE FILE(MASTER);
000070 CLOSE FILE(TIMECRD);
A breakpoint set on a compounded statement will treat that statement as a unit. For example, an explicit breakpoint will stop execution before or after an assignment statement is executed, if the assignment statement contains a function that returns a value.
Using the BEFORE and AFTER Commands
The following commands will stop execution before every procedure is executed and after statements 26 and 29 have executed:
The message 2 COMMAND(S) COMPLETED is displayed. When Enter is pressed and you scroll forward, you can see the results of the commands. See to the following figure.
Result of Setting Before and After Breakpoints
000021 N_CNTR = 0;
000022 OPEN FILE(INFILE);
000023 OUT_OF_RECS = ’0’B;
000024 END INIT_PARA;
------
000025 B ANALYZE_NEXT_REC: PROC;
000026 A READ FILE(INFILE) SET(IN_REC_PTR);
000027 IF ¨OUT_OF_RECS THEN DO;
000028 TRIANGLE_TYPE = 0;
000029 A CALL TRITSTP (WORK_REC,
------ TRIANGLE_TYPE);
000030 TX = TRIANGLE_TYPE;
000031 N_CNTR(TX) = N_CNTR(TX) + 1;
000032 END;
The after breakpoint on statement 26 will cause execution to pause after the READ statement is executed and before the next statement is executed. The after breakpoint on statement 29 causes execution to pause after the call to the external procedure TRITSTP is completed.
To stop execution on a statement in a procedure that is not currently displayed, you must qualify the procedure name using a colon (:). After the procedure name, enter the location where you want the breakpoint to be set. For example, the following:
sets a before breakpoint in the external procedure TRITSTP at the label DETERMINE_TYPE. The SOURCE command displays the external procedure TRITSTP. the following figure shows the result of the command.
Result of Qualifying a Breakpoint Command
COMMAND ===> SCROLL ===> CSR
PROGRAM: TRITSTP1 MODULE: TRIMAINP COMP DATE: 08/07/1995 COMP TIME: 12:15:45
** END **
------ ----------------------------------------- Before TRIMINP1/AMODE 31 <>
000011 A_N_C = A + C;
000012 B_N_C = B + C;
000013 IF (B_N_C ¨> A) | (A_N_C ¨> B) | (A_N_B ¨> C) THEN
------ TYPE_OF_TRIANGLE = 4;
000014 END VALIDATE_TRIANGLE;
------
000015 B DETERMINE_TYPE: PROC;
000016 SELECT;
000017 WHEN (TYPE_OF_TRIANGLE=4) ;
000028 WHEN (A = B & B = C) TYPE_OF_TRIANGLE = 1;
000019 WHEN (A = B | B = C | A = C)
------ TYPE_OF_TRIANGLE = 2;
000020 OTHERWISE TYPE_OF_TRIANGLE = 3;
000021 END;
000022 END DETERMINE_TYPE;
****************************** BOTTOM OF MODULE ****************************
Alternatively, you can establish qualification by using the SOURCE external procedure name command to display the source of a procedure that will be called and then set breakpoints at the desired locations. If the external procedure is not yet loaded in memory, or you need to qualify the procedure name by the load module in case of duplicates, enter SOURCE load module name::procedure name.
See to the Command-and-syntax-reference for detailed information about qualification rules for Code Debug TSO commands.
You can enter the SOURCE command without a keyword or press PF6 (LOCATE *) to return to the active procedure (TRIMAINP) where execution is currently paused.
You can use the DELETE command to remove breakpoints. The SHOW BREAKS command can be used to display a list of the breakpoints that are currently specified.
Using the INTERCEPT Command
The INTERCEPT command loads the specified procedure and sets a before breakpoint at the beginning of the procedure and an after breakpoint at the end. For example, if the following is entered,
the TRIRPTP procedure is displayed as shown in the following figure.
Result of the INTERCEPT Command
COMMAND ===> SCROLL ===> CSR
PROGRAM: TRIRPTP MODULE: TRIMAINP COMP DATE: 08/07/1995 COMP TIME: 12:15:45
** END **
------ ----------------------------------------- Before TRIMINP1/AMODE 31 <>
000001 B TRIRPTP: PROC(TABLE_OF_NAMES_N_CNTRS);
------
000002 DCL OUTFILE OUTPUT RECORD FILE
------ ENVIRONMENT(FB RECSIZE(80));
------
000003 DCL HDR_LINE STATIC CHAR(80) INIT
------ (’ *** TRIANGLE REPORT ***’);
000004 DCL 1 DTL_LINE,
------ 5 FILLER1 CHAR(11) INIT (' NUMBER OF '),
------ 5 DTL_TITLE CHAR(21),
------ 5 FILLER2 CHAR(05) INIT (''),
------ 5 DTL_CNTR PIC’ZZZZZ’,
------ 5 FILLER3 CHAR(38) INIT ('');
------
000005 DCL BLANK_LINE STATIC CHAR (80) INIT ('');
Using the GO Command
The GO command (PF12/PF24) is used to begin or resume execution of your procedure. The procedure will execute until a breakpoint is reached or an abend is intercepted by Code Debug TSO.
For example, in the TRIMAINP procedure, execution pauses when the before breakpoint is reached at the beginning of the main procedure. If the following is entered on the command line,
execution pauses at the after breakpoint on statement 22 as shown in the following figure.
The double execution arrow indicates an after breakpoint has been reached. A single execution arrow indicates a before breakpoint has been reached. The at sign (@) on statement 25 indicates that a before breakpoint was placed on the same line as the after breakpoint.
Result of Setting Breakpoints and Entering GO
====>> A OPEN FILE(INFILE);
000023 OUT_OF_RECS = ’0’B;
000024 END INIT_PARA;
------
000025 @ ANALYZE_NEXT_REC: PROC;
000026 READ FILE(INFILE) SET(IN_REC_PTR);
At this point, you could do any of the following:
- Set additional breakpoints
- Enter GO to resume execution
- Enter GO 1 to step through the procedure line-by-line
- Enter EXIT to exit from the debugging session
- Enter the RETEST command to obtain a fresh copy of the program.
Setting conditional breakpoints
The GO n, COUNT, WHEN, and TRACE commands are used to stop execution when a specified condition occurs.
Using the GO n Command
Using the GO command without any arguments resumes execution until the next breakpoint is reached, until Code Debug TSO intercepts an abend, or the procedures complete execution. The GO command can also conditionally execute a specified number of statements or procedures if an integer argument is entered with the command. For example,
executes five statements before pausing and
executes five labels before pausing.
Using the GO 1 command or pressing PF9 lets you single-step through the code to understand the effect of executing each statement. GO 1 single-steps at the statement level.
When a GO 1 command is issued from a statement that transfers control to an external procedure, execution pauses when control returns to the current procedure, unless a breakpoint is encountered within the called external procedure. For example, the following figure shows the result of entering the GO 1 command when execution is paused at the CALL to TRITSTP (statement 29) and no breakpoints are set in TRITSTP. Execution pauses at statement 30 when control returns to the main procedure TRIMAINP.
Single Stepping Within the Current Procedure
COMMAND ===> SCROLL ===> CSR
PROGRAM: TRIMINP1 MODULE: TRIMAINP COMP DATE: 08/07/1995 COMP TIME: 12:15:45
000007 TX > +00003 HALFWORD
000010 TRIANGLE_TYPE > +4 PACKED
** END **
------ -------------------------------------- Before TRIMINP1:30/AMODE 31 <>
------
000025 ANALYZE_NEXT_REC: PROC;
000026 READ FILE(INFILE) SET(IN_REC_PTR);
000027 IF ¨OUT_OF_RECS THEN DO;
000028 TRIANGLE_TYPE = 0;
000029 CALL TRITSTP (WORK_REC,
------ TRIANGLE_TYPE);
=====> TX = TRIANGLE_TYPE;
000031 N_CNTR(TX) = N_CNTR(TX) + 1;
000032 END;
000033 END ANALYZE_NEXT_REC;
------
000034 ENDING_PARA: PROC;
000035 CLOSE FILE(INFILE);
000036 CALL TRIRPTP (N_N_C_TABLE);
The following figure demonstrates the same example. However, enter the following to set a before breakpoint at the beginning of TRITSTP.
PROCEDURE NAME NOT FOUND IN MODULE SOURCE LISTING
Then, enter GOTO 29 to return to the CALL to TRITSTP statement. Now, when you press PF9 (GO 1), execution pauses in TRITSTP as shown in the following figure.
Stepping Into an External Procedure Using the GO 1 Command
COMMAND ===> SCROLL ===> CSR
BEFORE BREAKPOINT ENCOUNTERED
---
0000002 01 TST_REC > 123
0000003 TYPE_OF_TRIANGLE > +0 PACKED
** END **
------ ------------------------------------------ Before TRITSTP1/AMODE 31 <>
=====> B TRITSTP: PROC(TST_REC, TYPE_OF_TRIANGLE);
------
000002 DCL 1 TST_REC,
------ 5 A PIC’9’;
------ 5 B PIC’9’;
------ 5 C PIC’9’;
000003 DCL TYPE_OF_TRIANGLE FIXED DEC(1);
------
000004 DCL A_N_B PIC’999’;
000005 DCL B_N_C PIC’999’;
000006 DCL A_N_C PIC’999’;
------
------ /* */
------ /* */
------ /* START OF THE MAINLINE CODE */
Using the COUNT MAX Command
The COUNT command is used to monitor execution coverage by reporting the number of times a statement executes. When the MAX keyword is used with the COUNT command, you can specify the maximum number of times you want statements to execute. When the limit is reached, execution pauses and the message SPECIFIED EXECUTION MAX HAS BEEN REACHED is displayed. For example, to count the number of times statements 15 and 17 execute, up to a maximum of 3 times, enter the following:
When the COUNT command is issued, a 7-digit counter appears in columns 74 through 80 as shown in the following figure. The counter field can be typed over to set or remove the limit. For example, you can type over the counter with a higher limit and press Enter to raise the preset maximum limit, or you can zero out the counter and press Enter to remove the limit.
Result of Counting Statements With the MAX Keyword
000016 DO WHILE (¬OUT_OF_RECS);
=====> CALL ANALYZE_NEXT_REC; 00000003
000018 END;
000019 CALL ENDING_PARA;
Using the WHEN Command
The WHEN command lets you stop execution when a variable changes value or when a specified condition takes place. Code Debug TSO checks the condition after every statement in the current procedure and pauses if the condition is met. The WHEN command can be used with the following arguments:
Variable-name
Suspends execution when a statement altering the value of the variable is executed. The variable can be monitored by opening a Keep window and displaying the values. For example:
WHEN GRAND_TOTAL.TOTAL_SUM
WHEN PCB_PTR->IOPCB
WHEN PROCESS_CUST_DATA:CUST_REC
Condition
Suspends execution when the specified condition is met. You can enter a relational condition using expressions such as the following:
WHEN WORK_REC = ’345’
WHEN GRAND_TOTAL.TOTAL_SUM > 50000
For example, the following WHEN command will conditionally pause execution when the value of either the array N_CNTR changes or the subscript TX changes. The KEEP commands display the values of the variables.
WHEN N_CNTR(TX)
KEEP TX
KEEP N_CNTR(TX)
the following figure shows the result of resuming execution with PF12 (GO).
Result of Entering the When Command
COMMAND ===> SCROLL ===> CSR
WHEN N_CNTR (TX) CHANGES
000007 K TX > +00002 HALFWORD
S=2 OCCURS
000007 K 10 N_CNTR > 0001 ZONED
000007 TX > +00002 HALFWORD
000010 TRIANGLE_TYPE > +2 PACKED
------ ----------------------------------------- After TRIMINP1:30/AMODE 31 <>
------ TRIANGLE_TYPE);
====>> TX = TRIANGLE_TYPE;
000031 N_CNTR(TX) = N_CNTR(TX) + 1;
000032 END;
The DELETE WHEN command can be used to remove the when condition. The SHOW WHEN command can be used to display a list of the when conditions that are currently specified.
You can set a WHEN data change breakpoint before the addressability is established for the data. However, the following rules will apply:
- When will stop when storage is explicitly allocated and freed for a controlled variable.
- When will stop when the value of a pointer changes from SYSNULL (X’00000000’) or NULL (X’FF000000’) for a based variable, but it will not change when the address of the pointer changes.
- When will not stop when the addressability is gained or lost for automatic and static variables.
- WHEN conditional expression cannot evaluate the condition until the variables referenced establishes addressability.
Using the Inserted PAUSE Command
The PAUSE command can be dynamically inserted in the PL/I source code to set a breakpoint following the execution of a statement. You can specify a condition in which the pause breakpoint is to occur, by also inserting the IF...ELSE construct associated with it.
The PAUSE command must be used in conjunction with the INSERT command. For information on the usage convention of the INSERT command, see to Inserting Statements.
the following figure shows the effect of inserting a PAUSE command within a block of inserted Code Debug TSO commands.
Result of Encountering a Pause Breakpoint
COMMAND ===> SCROLL===> CSR
PAUSE REQUESTED BY INSERTED COMMAND
IN_REC_PTR =00207D50
----+----1----+----2----+----3
SAME-> K IN_REC > 111
** END **
------ ---------------------------------------- Before TRIMINP1:28/AMODE 31 <>
------
000025 ANALYZE_NEXT_REC: PROC;
000026 READ FILE(INFILE) SET(IN_REC_PTR);
000027 IF ¬OUT_OF_RECS THEN DO;
000028 TRIANGLE_TYPE = 0;
'''''' IF IN_REC = '345'
'''''' KEEP IN_REC
'''''' MOVE '111' TO IN_REC
=====> PAUSE
'''''' END-IF
000029 CALL TRITSTP (WORK_REC,
------ TRIANGLE_TYPE);
000030 TX = TRIANGLE_TYPE;
000031 N_CNTR(TX) = N_CNTR(TX) + 1;
000032 END;
Using the TRACE Command
The TRACE command is used to monitor the execution of statements, labels, and external procedures. The specified statements are highlighted as they are executed until a breakpoint is reached, an abend is intercepted by Code Debug TSO, a terminal I/O is issued, or a keyboard interrupt is detected.
Tracing is recorded in the session log. Use the LOG command to view the results of the trace.
When the TRACE command is used with the MAX keyword, the tracing function pauses when the number of executions reaches the preset limit. The default maximum limit is 25.
For example, if you request Code Debug TSO to trace execution at the statement level for a procedure that does not have any breakpoints set and to resume execution, the procedure will pause following the execution of 25 statements. the following figure demonstrates the result of entering the following command and pressing PF12 (GO):
Result of Entering the TRACE ALL STATEMENTS and GO Commands
COMMAND ===> SCROLL ===> CSR
25 TRACE BREAKPOINTS HAVE BEEN EXECUTED
IN_REC @00218C10
---
000011 01 WORK_REC > 124
000010 TRIANGLE_TYPE > +0 PACKED
** END **
------ --------------------------------------- Before TRIMINP1:29/AMODE 31 <>
000026 READ FILE(INFILE) SET(IN_REC_PTR);
000027 IF ¬OUT_OF_RECS THEN DO;
000028 TRIANGLE_TYPE = 0;
=====> CALL TRITSTP (WORK_REC,
------ TRIANGLE_TYPE);
000030 TX = TRIANGLE_TYPE;
000031 N_CNTR(TX) = N_CNTR(TX) + 1;
In order to override the default maximum limit, you must enter the MAX keyword with an integer other than 25 as an argument with the TRACE command.
The tracing speed can be controlled by using the SET DELAY command prior to entering the TRACE command. For instance, entering the following command will slow down the execution speed to one second:
You can interrupt tracing and suspend execution by using the Attention key. While tracing is in progress, the keyboard is unlocked and, depending upon your terminal type and network configuration, you may be able to use other keys to stop tracing. To end a TRACE command, use DELETE TRACE.