Debugging allows you to detect, diagnose, and eliminate errors in
a program. You can debug your ILE programs by using the ILE source debugger.
This chapter describes how to use the ILE source debugger.
This chapter describes how to:
- Prepare your ILE program for debugging
- Start a debug session
- Add and remove programs from a debug session
- View the program source from a debug session
- Set and remove conditional and unconditional breakpoints
- Step through a program
- Display the value of variables
- Change the value of variables
- Display the attributes of variables
- Equate a shorthand name to a variable, expression, or debug
command.
While debugging and testing your
programs, ensure that your library list is changed to direct the programs to a
test library containing test data so that any existing real data is not
affected.
You can prevent database files in
production libraries from being modified unintentionally by using one of the
following commands:
- Use the Start Debug (STRDBG) command and retain the default *NO
for the UPDPROD parameter.
- Use the Change Debug (CHGDBG) command.
See the CL section of the Programming category of the iSeries Information Center for more information.
See ILE Concepts book,
Chapter 10, "Debugging Considerations", for more information on the
ILE source debugger (including authority required to debug a program or service
program and the effects of optimization levels).
The ILE source debugger is used to detect errors in and eliminate
errors from program objects and service programs. You can use the source
debugger to:
- Debug any ILE CL or mixed ILE language application
- Monitor the flow of a program by using the debug commands while
the program is running.
- View the program source
- Set and remove conditional and unconditional breakpoints
- Step through a specified number of statements
- Display or change the value of variables
- Display the attributes of a variable
When a program stops because of a
breakpoint or a step command, the applicable module object's view is shown on
the display at the point where the program stopped. At this point you can enter
more debug commands.
Before you can use the source
debugger, you must use the debug options (DBGVIEW) when you create a module
object or program object using Create CL Module (CRTCLMOD) or Create Bound CL
(CRTBNDCL). After you set the breakpoints or other ILE source debugger options,
you can call the program.
Many debug commands are available for use with the ILE source debugger.
The debug commands and their parameters are entered on the debug command line
displayed on the bottom of the Display Module Source and Evaluate Expression
displays. These commands can be entered in upper case, lower case, or mixed
case.
Note:
The debug commands entered on the source debugger command line are
not CL commands.
Table
10-1 summarizes these debug
commands. The online help for the ILE source debugger describes the debug
commands and explains their allowed abbreviations.
Table 10-1.
ILE source debugger commands
Debug
Command
|
Description
|
ATTR
|
Permits you to
display the attributes of a variable. The attributes are the size and type of
the variable as recorded in the debug symbol table.
|
BREAK
|
Permits you to
enter either an unconditional or conditional breakpoint at a position in the
program being tested. Use BREAK position WHEN expression to enter a conditional breakpoint.
|
SBREAK
|
Permits you to
enter a service entry point at a position in the program being tested. A
service entry point is a type of breakpoint established in a program to
facilitate the system debugger in gaining control of a spawned job. The
breakpoint is only signaled when the job within which the service entry point
was hit is not currently under debug.
|
CLEAR
|
Permits you to
remove conditional and unconditional breakpoints.
|
DISPLAY
|
Allows you to
display the names and definitions assigned by using the EQUATE command. It
also allows you to display a different source module than the one currently
shown on the Display Module Source display. The module object must exist in
the current program object.
|
EQUATE
|
Allows you to
assign an expression, variable, or debug command to a name for shorthand use.
|
EVAL
|
Allows you to
display or change the value of a variable or to display the value of
expressions.
|
QUAL
|
Allows you to
define the scope of variables that appear in subsequent EVAL commands.
|
STEP
|
Allows you to
run one or more statements of the program being debugged.
|
FIND
|
Searches the
module currently displayed for a specified line-number or string or text.
|
UP
|
Moves the
displayed window of source towards the beginning of the view by the amount
entered.
|
DOWN
|
Moves the
displayed window of source towards the end of the view by the amount entered.
|
LEFT
|
Moves the
displayed window of source to the left by the number of characters entered.
|
RIGHT
|
Moves the
displayed window of source to the right the number of characters entered.
|
TOP
|
Positions the
view to show the first line.
|
BOTTOM
|
Positions the
view to show the last line.
|
NEXT
|
Positions the
view to the next breakpoint in the source currently displayed.
|
PREVIOUS
|
Positions the
view to the previous breakpoint in the source currently displayed.
|
HELP
|
Shows the
online help information for the available source debugger commands.
|
SET
|
Specifies if
case sensitive or case insensitive searching is performed for all subsequent
FIND requests in the current debug session. It also allows you to change the
update production files value.
|
WATCH
|
Displays a list
of the currently active watch conditions.
|
Before you can use the ILE source
debugger, you must use either the CRTCLMOD or CRTBNDCL command and specify the
DBGVIEW option.
For each ILE CL module object
that you want to debug, you can create one of three views:
- Root source view
- Listing view
- Statement view
A root source view contains the source statements of the source
member.
To use the root source view with
the ILE source debugger, the ILE CL compiler creates the root source view while
the module object (*MODULE) is being created.
Note:
The module object is created by using references to locations of
the source statements in the root source member instead of copying the source
statements into the view. Therefore, you should not modify, rename, or move
root source members between the creation of the module and the debugging of the
module created from these members.
To debug an ILE CL module object
by using a root source view, use the *SOURCE or *ALL option on the DBGVIEW parameter for
either the CRTCLMOD or CRTBNDCL commands.
One way to create a root source
view, is as follows:
CRTCLMOD
MODULE(MYLIB/MYPGM) SRCFILE(MYLIB/QCLLESRC) SRCMBR(MYPGM) TEXT('CL Program')
DBGVIEW(*SOURCE)
The Create CL Module (CRTCLMOD)
command with *SOURCE for the DBGVIEW parameter creates a root source view for
module object MYPGM.
A listing view is similar to the source code portion of the
compile listing or spool file produced by the ILE CL compiler.
To debug an ILE CL module object
by using a listing view, use the *LIST or *ALL option on the DBGVIEW parameter for
either the CRTCLMOD or CRTBNDCL commands when you create the module.
One way to create a listing view
is as follows:
CRTCLMOD
MODULE(MYLIB/MYPGM) SRCFILE(MYLIB/QCLLESRC) SRCMBR(MYPGM) TEXT('CL Program')
DBGVIEW(*LIST)
A statement view does not contain any CL source data. However,
breakpoints can be added by using procedure names and statement numbers found
in the compiler listing. To debug an ILE CL module object using a statement
view, you need a copy of the compiler listing.
Note:
No data is shown in the Display Module Source display when a
statement view is used to debug an ILE CL module object.
To debug an ILE CL module object
by using a statement view, use the *STMT, *SOURCE, *LIST, or *ALL option on the DBGVIEW parameter for
either the CRTCLMOD or CRTBNDCL commands when you create the module.
One way to create a statement
view is as follows:
CRTCLMOD
MODULE(MYLIB/MYPGM) SRCFILE(MYLIB/QLSRC) SRCMBR(MYPGM) TEXT('CL Program')
DBGVIEW(*STMT)
After you create
the debug view, you can begin debugging your application.
To start the ILE source debugger,
use the Start Debug (STRDBG) command. Once the debugger is started, it remains
active until you enter the End Debug (ENDDBG) command.
Initially, you can add as many as
twenty (20) program objects and twenty (20) service programs to a debug
session. Do this by using the Program (PGM) and Service Program (SRVPGM)
parameters on the STRDBG command. The program objects can be any combination of
ILE or original program model (OPM) programs. To start a debug session with
three program objects, type:
STRDBG PGM(*LIBL/MYPGM1 *LIBL/MYPGM2 *LIBL/MYPGM3) SRVPGM(*LIBL/SRVPGM1 *LIBL/SRVPGM2)
DBGMODSRC(*YES)
Note:
You must have *CHANGE authority to a program object to add it to a
debug session.
After entering the STRDBG
command, the Display Module Source display appears for ILE program objects. The
first module object bound to the program object with debug data is shown.
The option to use the ILE source
debugger to debug OPM programs exists for users. OPM programs contain source
debug data when created. Do this only by specifying the OPTION(*SRCDBG) parameter
of the Create CL Program (CRTCLPGM) command. The source debug data is actually
part of the program object.
To add OPM programs that are
created containing source debug data to the ILE source debugger, use the
Program (PGM) and OPM Source Level Debug (OPMSRC) parameters on the STRDBG
command. To start a debug session with an OPM program created with source debug
data, type:
STRDBG PGM(*LIBL/MYOPMPGM) OPMSRC(*YES) DSPMODSRC(*YES)
You can add more
program objects to a debug session after starting the session.
To add ILE program objects and
service programs to a debug session, use option 1 (Add program) and type the
name of the program object on the first line of the Work with Module List
display. See Table
10-1 for a list of ILE source
debugger commands. The Work with Module List display can be accessed from the
Display Module Source display by pressing F14 (Work with Module List). To add a
service program, change the default program type from *PGM to *SRVPGM. There is
no limit to the number of ILE program objects and service programs that can be
included in a debug session at any given time.
Figure 10-1.
Adding an ILE Program Object to a Debug Session. When the Enter is pressed, program
WEEKDAY2 is added to the debug session
+--------------------------------------------------------------------------------+
| Work with Module List |
| System: SYSTEM01 |
| Type options, press enter. |
| 1=Add program 4=Remove program 5=Display module source |
| 8=Work with module breakpoints |
| |
| Opt Program/module Library Type |
| 1 weekday2 *LIBL *PGM |
| DSPWKDAY MYLIB *PGM |
| DSPWKDAY *MODULE Selected |
| AABP1 *MODULE |
| |
| |
| |
| |
| |
| |
| |
| |
| Bottom |
| Command |
| ===> |
| F3=Exit F4=Prompt F5=Refresh F9=Retrieve F12=Cancel |
| |
+--------------------------------------------------------------------------------+
Figure 10-2.
Adding an ILE Program Object to a Debug Session. The information message at the bottom of
the display shows that program WEEKDAY2 was added to the debug session.
+--------------------------------------------------------------------------------+
| Work with Module List |
| System: SYSTEM01 |
| Type options, press enter. |
| 1=Add program 4=Remove program 5=Display module source |
| 8=Work with module breakpoints |
| |
| Opt Program/module Library Type |
| WEEKDAY2 *LIBL *PGM |
| WEEKDAY2 MYLIB *PGM |
| WEEKDAY2 *MODULE |
| DSPWKDAY MYLIB *PGM |
| DSPWKDAY *MODULE Selected |
| AABP1 *MODULE |
| |
| |
| |
| |
| |
| |
| Bottom |
| Command |
| ===> |
| F3=Exit F4=Prompt F5=Refresh F9=Retrieve F12=Cancel |
| Program WEEKDAY2 added to source debugger. |
+--------------------------------------------------------------------------------+
When you have finished adding
program objects to the debug session, press F3 (Exit) from the Work with Module
List display to return to the Display Module Source display. You can also use
option 5 (Display Module Source) to select and display a module.
To add OPM programs to a debug
session, use the Add Program (ADDPGM) command. A debug session can include up
to twenty (20) OPM programs at any given time. You can add OPM programs that
contain source debug data to the debug session by using option 1 (Add program)
on the Work with Module List display. (This is true provided the debug session
allows OPM source level debugging.) You can allow OPM source level debugging by
starting the debug session and by using the OPMSRC parameter on the STRDBG
command. If the OPMSRC parameter was not specified on the STRDBG command,
activate OPM source level debugging. Do this by using the OPM Source Level
Debug (OPMSRC) parameter on the Change Debug (CHGDBG) command. Alternately, you
can change the value of the OPM source debug support option by using the SET
debug command.
You can remove
program objects from a debug session after starting the session.
To remove ILE program objects and
service programs from a debug session, use option 4 (Remove program), next to
the program object you want to remove, on the Work with Module List display.
See Figure
10-3. The Work with Module List display can be accessed from the Display
Module Source display by pressing F14 (Work with Module List). To remove a
service program, change the default program type from *PGM to *SRVPGM.
Figure 10-3.
Removing an ILE Program Object from a Debug Session. When the Enter key is pressed, program
WEEKDAY2 is removed from the debug session.
+--------------------------------------------------------------------------------+
| Work with Module List |
| System: SYSTEM01 |
| Type options, press enter. |
| 1=Add program 4=Remove program 5=Display module source |
| 8=Work with module breakpoints |
| |
| Opt Program/module Library Type |
| *LIBL *PGM |
| 4 WEEKDAY2 MYLIB *PGM |
| WEEKDAY2 *MODULE |
| DSPWKDAY MYLIB *PGM |
| DSPWKDAY *MODULE Selected |
| AABP1 *MODULE |
| |
| |
| |
| |
| |
| |
| Bottom |
| Command |
| ===> |
| F3=Exit F4=Prompt F5=Refresh F9=Retrieve F12=Cancel |
| |
+--------------------------------------------------------------------------------+
Figure 10-4.
Removing an ILE Program Object from a Debug Session
+--------------------------------------------------------------------------------+
| Work with Module List |
| System: SYSTEM01 |
| Type options, press enter. |
| 1=Add program 4=Remove program 5=Display module source |
| 8=Work with module breakpoints |
| |
| Opt Program/module Library Type |
| *LIBL *PGM |
| DSPWKDAY MYLIB *PGM |
| DSPWKDAY *MODULE Selected |
| AABP1 *MODULE |
| |
| |
| |
| |
| |
| |
| |
| |
| Bottom |
| Command |
| ===> |
| F3=Exit F4=Prompt F5=Refresh F9=Retrieve F12=Cancel |
| Program WEEKDAY2 removed from source debugger. |
+--------------------------------------------------------------------------------+
When you have finished removing
program objects from the debug session, press F3 (Exit) from the Work with
Module List display to return to the Display Module Source display.
Note:
You must have *CHANGE authority to a program to remove it from a
debug session.
To remove OPM programs from a
debug session, use the Remove Program (RMVPGM) command. If OPM source level
debugging is active, OPM programs that are created with source debug data may
be listed on the Work with Module List display. You can remove these programs
from the debug session by using option 4 (Remove program) on the Work with
Module List display.
The Display Module Source display shows the source of a program object
one module object at a time. A module object's source can be shown if the
module object was compiled using one of the following debug view options:
- DBGVIEW(*ALL)
- DBGVIEW(*SOURCE)
- DBGVIEW(*LISTING)
There are two methods to change
what is shown on the Display Module Source display:
- Change a view
- Change a module
When you change a view, the ILE
source debugger maps to equivalent positions in the view you are changing to.
When you change the module, the executable statement on the displayed view is
stored in memory and is viewed when the module is displayed again. Line numbers
that have breakpoints set are highlighted. When a breakpoint, step, or message
causes the program to stop and the display to be shown, the source line where
the event occurred is highlighted.
You can change the module object that is
shown on the Display Module Source display by using option 5 (Display module
source) on the Work with Module List display. The Work with Module List display
can be accessed from the Display Module Source display by pressing F14 (Work
with Module List). The Display Module Source display is shown in Figure
10-5.
To select a module object, type 5
(Display module source) next to the module object you want to show.
Figure 10-5.
Display a Module View
+--------------------------------------------------------------------------------+
| Display Module Source |
| |
| Program: DSPWKDAY Library: MYLIB Module: DSPWKDAY |
| 24 500- CALL PGM(WEEKDAY2) PARM(&DAYOFWK) |
| 25 600- IF COND(&DAYOFWK *EQ 1) THEN(CHGVAR + |
| 26 700 VAR(&WEEKDAY) VALUE('Sunday')) |
| 27 800- ELSE CMD(IF COND(&DAYOFWK *EQ 2) THEN(CHGV |
| 28 900 VAR(&WEEKDAY) VALUE('Monday'))) |
| 29 1000- ELSE CMD(IF COND(&DAYOFWK *EQ 3) THEN(CHGV |
| 30 1100 VAR(&WEEKDAY) VALUE('Tuesday'))) |
| 31 1200- ELSE CMD(IF COND(&DAYOFWK *EQ 4) THEN(CHGV |
| 32 1300 VAR(&WEEKDAY) VALUE('Wednesday'))) |
| 33 1400- ELSE CMD(IF COND(&DAYOFWK *EQ 5) THEN(CHGV |
| 34 1500 VAR(&WEEKDAY) VALUE('Thursday'))) |
| 35 1600- ELSE CMD(IF COND(&DAYOFWK *EQ 6) THEN(CHGV |
| 36 1700 VAR(&WEEKDAY) VALUE('Friday'))) |
| 37 1800- ELSE CMD(IF COND(&DAYOFWK *EQ 7) THEN(CHGV |
| 38 1900 VAR(&WEEKDAY) VALUE('Saturday'))) |
| More... |
| Debug . . . |
| |
| F3=End program F6=Add/Clear breakpoint F10=step F11=Display variable |
| F12=Resume F17=Watch variable F18=Work with watch F24=More keys |
| |
+--------------------------------------------------------------------------------+
After you select the module
object that you want to view, press Enter. The selected module object is shown
in the Display Module Source display.
An alternate method of changing a
module object is to use the DISPLAY debug command. On the debug command line,
type:
DISPLAY MODULE module-name
The module object module-name will now be shown. The module object
must exist in a program or service program object that has been added to the
debug session.
Several views of an ILE CL module object
are available depending on the values you specify when you create an ILE CL
module object. These views are:
- Root source view
- Listing view
- Statement view
You can change the view of the
module object that is shown on the Display Module Source display through the
Select View display. The Select View display can be accessed from the Display
Module Source display by pressing F15 (Select View). The Select View display is
shown in Figure
10-6. The current view is listed at the top of the window, and the other
views that are available are shown below. Each module object in a program
object can have a different set of views available, depending on the debug
options used to create it.
To select a view, type 1 (Select)
next to the view you want to show.
Figure 10-6.
Changing a View of a Module Object
+--------------------------------------------------------------------------------+
| Display Module Source |
| .............................................................................. |
| : Select View : |
| : : |
| : Current View . . . : CL Root Source : |
| : : |
| : Type option, press Enter. : |
| : 1=Select : |
| : : |
| : Opt View : |
| : CL Root Source : |
| : 1 CL Listing View : |
| : : |
| : : |
| : Bottom : |
| : F12=Cancel : |
| : : |
| :............................................................................: |
| More... |
| Debug . . . |
| |
| F3=End Program F6=Add/Clear breakpoint F10=Step F11=Display variable |
| F12=Resume F17=Watch variable F18=Work with watch F24=More keys |
| |
+--------------------------------------------------------------------------------+
After you select the view of the
module object that you want to show, press Enter and the selected view of the
module object is shown in the Display Module Source display.
You
can use breakpoints to halt a program object at a specific point when it is
running. An unconditional
breakpoint stops the program
object at a specific statement. A conditional
breakpoint stops the program
object when a specific condition at a specific statement is met.
When the program object stops,
the Display Module Source display is shown. The appropriate module object is
shown with the source positioned at the line where the breakpoint occurred.
This line is highlighted. At this point, you can evaluate variables, set more
breakpoints, and run any of the debug commands.
You should know the following
characteristics about breakpoints before using them:
- When a breakpoint is bypassed, for example with the GOTO statement, that breakpoint isn't processed.
- When a breakpoint is set on a statement, the breakpoint occurs
before that statement is processed.
- When a statement with a conditional breakpoint is reached, the
conditional expression associated with the breakpoint is evaluated before
the statement is processed.
- Breakpoint functions are specified through debug commands.
These
functions include:
- Adding breakpoints to program objects
- Removing breakpoints from program objects
- Displaying breakpoint information
- Resuming the running of a program object after a
breakpoint has been reached.
You
can set or remove an unconditional breakpoint by using:
- F6 (Add/Clear breakpoint) from the Display Module Source display
- F13 (Work with Module Breakpoints) from the Display Module Source
display
- The BREAK debug command to set a breakpoint
- The CLEAR debug command to remove a breakpoint
The simplest way to set and
remove an unconditional breakpoint is to use F6 (Add/Clear breakpoint) from the
Display Module Source display. To set an unconditional breakpoint using F6,
place your cursor on the line to which you want to add the breakpoint and press
F6. An unconditional breakpoint is then set on the line. To remove an
unconditional breakpoint, place your cursor on the line from which you want to
remove the breakpoint and press F6. The breakpoint is then removed from the
line.
Repeat the previous steps for
each unconditional breakpoint you want to set.
Note:
If the line on which you want to set a breakpoint is not a
runnable statement, the breakpoint is set at the next runnable statement.
After the breakpoints are set,
press F3 (Exit) to leave the Display Module Source display. You can also use
F21 (Command Line) from the Display Module Source display to call the program
from a command line.
Call the program object. When a
breakpoint is reached, the program stops and the Display Module Source display
is shown again. At this point, you can evaluate variables, set more
breakpoints, and run any of the debug commands.
An alternate method of setting
and removing unconditional breakpoints is to use the BREAK and CLEAR debug
commands.
To set an unconditional
breakpoint by using the BREAK debug command, type:
BREAK line-number
on the debug command line. Line-number is the line number in the currently
displayed view of the module object on which you want to set a breakpoint.
To remove an unconditional
breakpoint by using the CLEAR debug command, type:
CLEAR line-number
on the debug command line. Line-number is the line number in the currently
displayed view of the module object from which you want to remove a breakpoint.
If using the statement view,
there is no line numbers displayed. To set unconditional breakpoints in the
statement view, type:
BREAK procedure-name/statement-number
on the debug command line. Procedure-name is the name of your CL module. Statement-number(from the
compiler listing) is the statement number where you wanted to stop.
You
can set or remove a conditional breakpoint by using:
- The Work with Breakpoints display
- The BREAK debug command to set a breakpoint
- The CLEAR debug command to remove a breakpoint
Note:
The relational operators supported for conditional breakpoints are
<, >, =, <=, >=, and <> (not equal).
One way you can set or remove
conditional breakpoints is through the Work with Module Breakpoints display.
The Work with Module Breakpoints display can be accessed from the Display
Module Source display by pressing F13 (Work with Module Breakpoints). The Work with
Module Breakpoints display is shown in Figure
10-7. To set a conditional breakpoint, type the following:
- 1 (Add) in the Opt field,
- the debugger line number where you want to set
the breakpoint in the Line field,
- a conditional expression in the Condition field,
and press Enter. For example, to
set a conditional breakpoint at debugger line 35, as shown in Figure
10-7, type the following:
- 1 (Add) in the Opt field,
- 35 in the Line field,
- type &I=21 in the Condition field,
and press Enter.
To remove a conditional
breakpoint, type 4 (Clear) in the Opt field next to the breakpoint you want
to remove, and press Enter. You can also remove unconditional breakpoints in
this manner.
Figure 10-7.
Setting a Conditional Breakpoint
+--------------------------------------------------------------------------------+
| Work with Module Breakpoints |
| System: SYSTEM01 |
| Program . . . : MYPGM Library . . . : MYLIB |
| Module . . . : MYMOD Type . . . . . : *PGM |
| |
| Type options, press Enter. |
| 1=Add 4=Clear |
| |
| Opt Line Condition |
| 1 35____ &I=21______________________ |
| _ ______ ____________________________ |
+--------------------------------------------------------------------------------+
Repeat the previous steps for
each conditional breakpoint you want to set or remove.
Note:
If the line on which you want to set a breakpoint is not a
runnable statement, the breakpoint is set at the next runnable statement.
After you specify all breakpoints
that you want to set or remove, press F3 (Exit) to return to the Display Module
Source display.
Then press F3 (Exit) to leave the
Display Module Source display. You can also use F21 (Command Line) from the
Display Module Source display to call the program object from a command line.
Call the program object. When a
statement with a conditional breakpoint is reached, the conditional expression
associated with the breakpoint is evaluated before the statement is run. If the
result is false, the program object continues to run. If the result is true,
the program object stops, and the Display Module Source display is shown. At
this point, you can evaluate variables, set more breakpoints, and run any of
the debug commands.
An alternate method of setting and removing conditional
breakpoints is to use the BREAK and CLEAR debug commands.
To set a conditional breakpoint
by using the BREAK debug command, type:
BREAK line-number WHEN expression
on the debug command line. Line-number is the line number in the currently
displayed view of the module object on which you want to set a breakpoint. expression is the conditional expression that is
evaluated when the breakpoint is encountered. The relational operators
supported for conditional breakpoints are <, >, =, <=, >=, and
<> (not equal).
In non-numeric conditional
breakpoint expressions, the shorter expression is implicitly padded with blanks
before the comparison is made. This implicit padding occurs before any National
Language Sort Sequence (NLSS) translation. SeeNational
Language Sort Sequence (NLSS) for
more information on NLSS.
To remove a conditional
breakpoint by using the CLEAR debug command, type:
CLEAR line-number
on the debug command line. Line-number is number in the currently displayed
view of the module object from which you want to remove a breakpoint.
In the statement view, no line
numbers are displayed. To set conditional breakpoints in the statement view,
type:
BREAK procedure-name/statement-name WHEN expression
on the debug command line. Procedure-name is the name of your CL module. Statement-number(from the
compiler listing) is the statement number where you want to stop.
Non-numeric
conditional breakpoint expressions are divided into the following two types:
- Char- 8: each character contains 8 bits
- Char-16: each character contains 16 bits (DBCS)
NLSS applies only to non-numeric
conditional breakpoint expressions of type Char-8. See Table
10-2 for the possible combinations
of non-numeric conditional breakpoint expressions.
The sort sequence table used by
the source debugger for expressions of type Char-8 is the sort sequence table
specified for the SRTSEQ parameter on the CRTCLMOD or CRTBNDCL commands.
If the resolved sort sequence
table is *HEX, no sort sequence table is used. Therefore, the source debugger
uses the hexadecimal values of the characters to determine the sort sequence.
Otherwise, the specified sort sequence table is used to assign weights to each
byte before the comparison is made. Bytes between, and including,
shift-out/shift-in characters are not assigned weights.
Note:
The name of the sort sequence table is saved during compilation.
At debug time, the source debugger uses the name saved from the compilation to
access the sort sequence table. If the sort sequence table specified at
compilation time resolves to something other than *HEX or *JOBRUN, it is
important the sort sequence table does not get altered before debugging is
started. If the table cannot be accessed because it is damaged or deleted, the
source debugger uses the *HEX sort sequence table.
Table 10-2.
Non-numeric Conditional Breakpoint Expressions
Type
|
Possibilities
|
Char-8
|
- Character variable compared to character
variable
- Character variable compared to character
literal 1
- Character variable compared to hex literal 2
- Character literal 1 compared to character variable
- Character literal 1 compared to character literal 1
- Character literal 1 compared to hex literal
&cont. 2
- Hex literal 2 compared to character variable 1
- Hex literal 2 compared to character literal 1
- Hex literal 2 compared to hex literal 2
|
Char 16
|
- DBCS character variable compared to DBCS
character variable
- DBCS character variable compared to graphic
literal 3
- DBCS character variable compared to hex literal 2
- Graphic literal 3 compared to DBCS character
variable
- Graphic literal 3 compared to Graphic literal 3
- Graphic literal 3 compared to hex literal 2
- Hex literal 2 compared to DBCS character
variable
- Hex literal 2 compared to Graphic literal 3
|
1
Character literal is of the form 'abc'.
2
Hexadecimal literal is of the form X'hex digits'.
3
Graphic literal is of the form G'<so>DBCS data<si>'.
Shift-out is represented as <so> and shift-in is represented as
<si>.
|
CL declarations: DCL VAR(&CHAR1) TYPE(*CHAR) LEN(1)
DCL VAR(&CHAR2) TYPE(*CHAR) LEN(2)
DCL VAR(&DEC1) TYPE(*DEC) LEN(3 1)
DCL VAR(&DEC2) TYPE(*DEC) LEN(4 1)
Debug command: BREAK 31 WHEN &DEC1 = 48.1
Debug command: BREAK 31 WHEN &DEC2 > &DEC1
Debug command: BREAK 31 WHEN &CHAR2 <> 'A'
Comment: 'A' is implicitly padded to
the right with one blank character before
the comparison is made.
Debug command: BREAK 31 WHEN %SUBSTR(&CHAR2 2 1) <= X'F1'
Debug command: BREAK 31 WHEN %SUBSTR(&CHAR2 1 1) >= &CHAR1
Debug command: BREAK 31 WHEN %SUBSTR(&CHAR2 1 1) < %SUBSTR(&CHAR2 2 1)
The %SUBSTR built-in function
allows you to substring a character string variable. The first argument must be
a string identifier, the second argument is the starting position, and the
third argument is the number of single byte or double byte characters.
Arguments are delimited by one or more spaces.
You can remove all breakpoints, conditional and unconditional,
from a program object that has a module object shown on the Display Module
Source display by using the CLEAR PGM debug command. To use the debug command,
type:
CLEAR PGM
on the debug command line. The
breakpoints are removed from all of the modules bound to the program or service
program.
After a
breakpoint is encountered, you can run a specified number of statements of a
program object, then stop the program again and return to the Display Module
Source display. The program object begins running on the next statement of the
module object in which the program stopped. Typically, a breakpoint is used to
stop the program object.
You can step through a program
object by using:
- F10 (Step) or F22 (Step into) on the Display
Module Source display
- The STEP debug command
The simplest way to step through
a program object one statement at a time is to use F10 (Step) or F22 (Step
into) on the Display Module Source display. When you press F10 (Step) or F22
(Step into), then next statement of the module object shown in the Display
Module Source display is run, and the program object is stopped again.
Note:
You cannot specify the number of statements to step through when
you use F10 (Step) or F22 (Step into). Pressing F10 (Step) or F22 (Step into)
performs a single step.
Another way to step through a
program object is to use the STEP debug command. The STEP debug command allows
you to run more than one statement in a single step.
The default
number of statements to run, using the STEP debug command, is one. To step
through a program object using the STEP debug command, type:
STEP number-of-statements
on the debug command line. Number-of-statementsis the
number of statements of the program object that you want to run in the next
step before the program object is halted again. For example, if you type
STEP 5
on the debug command line, the
next five statements of your program object are run, then the program object is
stopped again and the Display Module Source display is shown.
When a CALL statement to another
program object is encountered in a debug session, you can do either of the
following:
- Step over the called program object, or
- Step into the called program object.
If you choose
to step over the called program object, then the
CALL statement and the called program object are run as a single step. The
called program object is run to completion before the calling program object is
stopped at the next step. Step over is the default step mode.
If you choose to step into the called program object, then each
statement in the called program object is run as a single step. If the next
step at which the running program object is to stop falls within the called
program object, the called program object is halted at this point. The called
program object is then shown in the Display Module Source display if the called
program object is compiled with debug data and you have the correct authority
to debug it.
You can step over program objects
by using:
- F10 (Step) on the Display Module Source display
- The STEP OVER debug command
You can use F10 (Step) on the
Display Module Source display to step over a called program object in a debug
session. If the next statement to be run is a CALL statement to another program
object, then pressing F10 (Step) will cause the called program object to run to
completion before the calling program object is stopped again.
Alternatively,
you can use the STEP OVER debug command to step over a called program object in
a debug session. To use the STEP OVER debug command, type:
STEP number-of-statements OVER
on the debug command line. Number-of-statements is the number of statements of the
program object that you want to run in the next step before the program object
is halted again. If one of the statements that are run contains a CALL
statement to another program object, the ILE source debugger steps over the
called program object.
You can step
into program objects by using:
- F22 (Step into) on the Display Module Source
display
- The STEP INTO debug command
You can use F22 (Step into) on
the Display Module Source display to step into a called program object in a
debug session. If the next statement to be run is a CALL statement to another
program object, pressing F22 (Step into) causes the first statement in the
called program object to be run. The called program object is then shown in the
Display Module Source display.
Note:
The called program object must have debug data associated with it
in order for it to be shown in the Display Module Source display.
Alternatively,
you can use the STEP INTO debug command to step into a called program object in
a debug session. To use the STEP INTO debug command, type:
STEP number-of-statements INTO
on the debug command line. Number-of-statements is the number of statements of the
program object that you want to run in the next step before the program object
is halted again. If one of the statements that are run contains a CALL
statement to another program object, the debugger steps into the called program
object. Each statement in the called program object is counted in the step. If
the step ends in the called program object then the called program object is
shown in the Display Module Source display. For example, if you type
STEP 5 INTO
on the debug command line, the
next five statements of the program object are run. If the third statement is a
CALL statement to another program object, then two statements of the calling
program object are run and the first three statements of the called program
object are run.
You can
display the value of variables by using:
- F11 (Display variable) on the Display Module Source display
- The EVAL debug command
The scope of the variables used
in the EVAL command is defined by using the QUAL command. However, you do not
need to specifically define the scope of the variables contained in a CL module
because they are all of global scope.
To display a variable using F11
(Display variable), place your cursor on the variable that you want to display
and press F11. The current value of the variable is shown on the message line
at the bottom of the Display Module Source display.
Figure 10-8.
Displaying a Variable using F11 (Display variable). Using the EVAL Debug Command
+--------------------------------------------------------------------------------+
| Display Module Source |
| |
| Program: DSPWKDAY Library: MYLIB Module: DSPWKDAY |
| 4 DCL VAR(&MSGTEXT) TYPE(*CHAR) LEN(20) |
| 5 CALL PGM(WEEKDAY2) PARM(&DAYOFWK) |
| 6 IF COND(&DAYOFWK *EQ 1) THEN(CHGVAR + |
| 7 VAR(&WEEKDAY) VALUE('Sunday')) |
| 8 ELSE CMD(IF COND(&DAYOFWK *EQ 2) THEN(CHGVAR + |
| 9 VAR(&WEEKDAY) VALUE('Monday'))) |
| 10 ELSE CMD(IF COND(&DAYOFWK *EQ 3) THEN(CHGVAR + |
| 11 VAR(&WEEKDAY) VALUE('Tuesday'))) |
| 12 ELSE CMD(IF COND(&DAYOFWK *EQ 4) THEN(CHGVAR + |
| 13 VAR(&WEEKDAY) VALUE('Wednesday'))) |
| 14 ELSE CMD(IF COND(&DAYOFWK *EQ 5) THEN(CHGVAR + |
| 15 VAR(&WEEKDAY) VALUE('Thursday'))) |
| 16 ELSE CMD(IF COND(&DAYOFWK *EQ 6) THEN(CHGVAR + |
| 17 VAR(&WEEKDAY) VALUE('Friday'))) |
| 18 ELSE CMD(IF COND(&DAYOFWK *EQ 7) THEN(CHGVAR + |
| More... |
| Debug . . . |
| |
| F3=End program F6=Add/Clear breakpoint F10=Step F11=Display variable |
| F12=Resume F17=Watch Variable F18=Work with watch F24=More keys |
| &DAYOFWK = 3. |
+--------------------------------------------------------------------------------+
You can also use the EVAL debug
command to determine the value of a variable. To display the value of a
variable using the EVAL debug command, type:
EVAL variable-name
on the debug command line. Variable-name is the name of the variable that you
want to display. The value of the variable is shown on the message line if the
EVAL debug command is entered from the Display Module Source display and the
value can be shown on a single line. If the value cannot be shown on a single
line, it is shown on the Evaluate Expression display.
For example, to display the value
of the variable &DAYOFWK;
on line 7 of the module object shown in Figure
10-8, type:
EVAL &DAYOFWK
The message line of the Display
Module Source display shows &DAYOFWK = 3. as in Figure
10-8.
CL declarations: DCL VAR(&LGL1) TYPE(*LGL) VALUE('1')
Debug command: EVAL &LGL1
Result: &LGL1 = '1'
CL declarations: DCL VAR(&CHAR1) TYPE(*CHAR) LEN(10) VALUE('EXAMPLE')
Debug command: EVAL &CHAR1
Result: &CHAR1 = 'EXAMPLE '
Debug command: EVAL %SUBSTR(&CHAR1 5 3)
Result: %SUBSTR(&CHAR1 5 3) = 'PLE'
Debug command: EVAL %SUBSTR(&CHAR1 7 4)
Result: %SUBSTR(&CHAR1 7 4) = 'E '
The %SUBSTR built-in function
allows you to substring a character string variable. The first argument must be
a string identifier, the second argument is the starting position, and the
third argument is the number of single byte or double byte characters.
Arguments are delimited by one or more spaces.
CL declarations: DCL VAR(&DEC1) TYPE(*DEC) LEN(4 1) VALUE(73.1)
CL declarations: DCL VAR(&DEC2) TYPE(*DEC) LEN(3 1) VALUE(12.5)
Debug command: EVAL &DEC1
Result: &DEC1 = 073.1
Debug command: EVAL &DEC2
Result: &DEC2 = 12.5
You can use
the EVAL debug command to display the value of variables in hexadecimal format.
To display a variable in hexadecimal format, on the debug command line, type:
EVAL variable-name: x number-of-bytes
Variable-name is the name of the variable that you want
to display in hexadecimal format. 'x' specifies that the variable is to be
displayed in hexadecimal format and number-of-bytes indicates the number of bytes
displayed. If no length is specified after the 'x', the size of the variable is
used as the length. A minimum of 16 bytes is always displayed. If the length of
the variable is less than 16 bytes, then the remaining space is filled with zeroes until the 16 byte boundary is reached.
CL declaration: DCL VAR(&CHAR1) TYPE(*CHAR) LEN(10) VALUE('ABC')
DCL VAR(&CHAR2) TYPE(*CHAR) LEN(10) VALUE('DEF')
Debug command: EVAL &CHAR1:X 32
Result:
00000 C1C2C340 40404040 4040C4C5 C6404040 ABC DEF
00010 40404040 00000000 00000000 00000000 ............
You can
change the value of variables by using the EVAL command with the assignment
operator (=).
The scope of the variables used
in the EVAL command is defined by using the QUAL command. However, you do not
need to specifically define the scope of the variables contained in a CL module
because they are all of global scope.
You can use the EVAL debug
command to assign numeric, character, and hexadecimal data to variables
provided they match the definition of the variable.
To change the value of the
variable, type:
EVAL variable-name = value
on the debug command line. Variable-name is the name of the variable that you
want to change and value is an identifier or literal value that
you want to assign to variable-name.
For example,
EVAL &COUNTER = 3.0
changes the value of &COUNTER; to 3.0 and
shows
&COUNTER = 3.0 = 3.0
on the message line of the
Display Module Source display. The result is preceded by the variable-name and
value you are changing.
When you assign values to a
character variable, the following rules apply:
- If the length of the source expression is less
than the length of the target expression, the data is left justified in
the target expression and the remaining positions are filled with blanks.
- If the length of the source expression is greater
than the length of the target expression, the data is left justified in
the target expression and truncated to the length of the target
expression.
Note:
DBCS variables can be assigned any of the following:
·
Another DBCS variable
·
A graphic literal of the form G'<so>DBCS data<si>'
·
A hexadecimal literal of the form X'hex digits'
CL declarations: DCL VAR(&LGL1) TYPE(*LGL) VALUE('1')
DCL VAR(&LGL2) TYPE(*LGL)
Debug command: EVAL &LGL1
Result: &LGL1 = '1'
Debug command: EVAL &LGL1 = X'F0'
Result: &LGL1 = X'F0' = '0'
Debug command: EVAL &LGL2 = &LGL1
Result: &LGL2 = &LGL1 = '0'
CL declarations: DCL VAR(&CHAR1) TYPE(*CHAR) LEN(1) VALUE('A')
DCL VAR(&CHAR2) TYPE(*CHAR) LEN(10)
Debug command: EVAL &CHAR1 = 'B'
Result: &CHAR1 = 'B' = 'B'
Debug command: EVAL &CHAR1 = X'F0F1F2F3'
Result: &CHAR1 = 'F0F1F2F3' = '0'
Debug command: EVAL &CHAR2 = 'ABC'
Result: &CHAR2 = 'ABC' = 'ABC '
Debug command: EVAL %SUBSTR(CHAR2 1 2) = %SUBSTR(&CHAR2 3 1)
Result: %SUBSTR(CHAR2 1 2) = %SUBSTR(&CHAR2 3 1) = 'C '
Comment: Variable &CHAR contains 'C C '
The %SUBSTR built-in function
allows you to substring a character string variable. The first argument must be
a string identifier, the second argument is the starting position, and the
third argument is the number of single byte or double byte characters.
Arguments are delimited by one or more spaces.
CL declarations: DCL VAR(&DEC1) TYPE(*DEC) LEN(3 1) VALUE(73.1)
DCL VAR(&DEC2) TYPE(*DEC) LEN(2 1) VALUE(3.1)
Debug command: EVAL &DEC1 = 12.3
Result: &DEC1 = 12.3 = 12.3
Debug command: EVAL &DEC1 = &DEC2
Result: &DEC1 = &DEC2 = 03.1
The Attribute
(ATTR) debug command permits you to display the attributes of a variable. The
attributes are the size (in bytes) and type of the variable as recorded in the
debug symbol table on Table
10-1.
The following is an example using
the ATTR debug command.
CL declaration: DCL VAR(&CHAR2) TYPE(*CHAR) LEN(10)
Debug command: ATTR &CHAR2
Result: TYPE = FIXED LENGTH STRING, LENGTH = 10 BYTES
CL declaration: DCL VAR(&DEC) TYPE(*DEC) LEN(3 1)
Debug command: ATTR &DEC
Result: TYPE = PACKED(3,1), LENGTH = 2 BYTES
You can use the EQUATE debug command to
equate a name with a variable, expression or debug command for shorthand use.
You can then use that name alone or within another expression. If you use it
within another expression, the value of the name is determined before the
expression is evaluated. These names stay active until a debug session ends or
a name is removed.
To equate a name with a variable,
expression or debug command, type:
EQUATE shorthand-name definition
on the debug command line. shorthand-name is the name that you want to equate
with a variable, expression, or debug command, and definition is the variable, expression, or debug
command that you are equating with the name.
For example, to define a
shorthand name called DC that displays the contents of a
variable called &COUNTER,
type:
EQUATE DC EVAL &COUNTER
on the debug command line. Now,
each time DC is typed on the debug command line,
the command EVAL &COUNTER is performed.
The maximum number of characters
that can be typed in an EQUATE command is 144. If a definition is not supplied
and a previous EQUATE command defined the name, the previous definition is
removed. If the name was not previously defined, an error message is shown.
To see the names that have been
defined with the EQUATE debug command for a debug session, type:
DISPLAY EQUATE
on the debug command line. A list
of the active names is shown on the Evaluate Expression display.
The following
conditions exist when you are working with source debug National Language
Support for ILE CL.
- When a view is displayed on the Display Module
Source display, the source debugger converts all data to the Coded
Character Set Identifier (CCSID) of the debug job.
- When assigning literals to variables, the source
debugger does not perform CCSID conversion on quoted literals (for example
'abc'). Also, quoted literals are case sensitive.
The following
condition is true only when you are working with the CL Root Source View:
- If the source file CCSID is different from the module CCSID, the source
debugger may not recognize a CL identifier containing variant characters
(#, @, $)
The CCSID of the module can be
found using the Display Module (DSPMOD) CL command. If you need to work with CL
Root Source View and the source file CCSID is different from the module CCSID,
you can take one of the following actions:
- Ensure the CCSID of CL source is the same as the
CCSID of the compile-time job.
- Change the CCSID of the compile-time job to 65
535 and compile.
- Use the CL Listing View if the previous two
options are not possible.
See the ILE Concepts book,
Chapter 10, "Debugging Considerations" for more information on
national language Restrictions for Debugging.
Using COPY,
SAVE, RESTORE, CRTDUPOBJ, and CHKOBJITG while Debugging
Breakpoints or steps may be temporarily removed from a program while debugging when
you use certain control language (CL) commands to specify your library or
program. Breakpoints and steps are restored when the CL command completes running.
A CPD190A message will be in the job log when the breakpoints or steps are
removed; another CPD190A message will be in the job log when the breakpoints or
steps are restored.
The following are the CL commands
which can cause the breakpoint or step to be temporarily removed:
CHKOBJITG
|
CPY
CPYLIB
|
CPROBJ
CRTDUPOBJ
|
RSTLIB
RSTOBJ
|
SAVLIB
SAVOBJ
SAVSYS
SAVCHGOBJ
|
Note:
When the CL commands are operating on the program, you will
receive error message CPF7102 when you issue the BREAK or STEP command.
Testing functions are designed to help you
write and maintain your applications. It lets you run your programs in a
special testing environment while closely observing and controlling the processing
of these programs in the testing environment. You can interact with your
programs using the testing functions described in this chapter. These functions
are available through a set of commands that can be used interactively or in a
batch job. The functions allow you to:
- Trace a program's processing sequence and show
the statements processed and the values of program variables at each point
in the sequence.
- Stop at any statement in a program (called a
breakpoint) and receive control to perform a function such as displaying
or changing a variable value or calling another user-defined program.
No special commands specifically
for testing are contained in the program being tested. The same program being
tested can be run normally without changes. All test commands are specified
within the job the program is in, not as a permanent part of the program being
tested. With the testing commands, you interact with the programs symbolically
in the same terms as the high-level language (HLL) program was written in. You
refer to variables by their names and statements by their numbers. (These are
the numbers used in the program's source list.) In addition, the test functions
are only applicable to the job they are set up in. The same program can be used
at the same time in another job without being affected by the testing functions
set up.
To begin testing, your program must be put
in debug mode. Debug mode is a special environment in which the testing
functions can be used in addition to the normal system functions. Testing
functions cannot be used outside debug mode. To start debug mode, you must use
the Start Debug (STRDBG) command. In addition to placing your program in debug
mode, the STRDBG command lets you specify certain testing information such as
the programs that are being debugged. Your program remains in debug mode until
an End Debug (ENDDBG) or Remove Program (RMVPGM) command is encountered or your
current routing step ends.
Note: If the System Debug Manager
function in iSeries Navigator has been used to select Debug in order to check
the system, then issuing the Start Debug (STRDBG) command will cause the
graphical interface to be presented. In this case, whenever one of the users
specified in the user list issues the STRDBG command, they will see the iSeries
Navigator System Debug Manager rather than the Command Entry display. If the
ENDDBG command is entered and Debug in the System Debug Manager is not
currently selected, then issuing the STRDBG command will again invoke the
system debugger using the Command Entry display.
The following STRDBG command
places the job in debug mode and adds program CUS310 as the program to be
debugged.
STRDBG PGM(CUS310)
The option exists to use the ILE
source debugger to debug OPM programs. To create OPM programs that contain
source debug data, specify the OPTION(*SRCDBG) parameter on the Create CL
Program (CRTCLPGM) command. The source debug data is actually part of the
program object.
To add OPM programs that get
created containing source debug data to the ILE source debugger, use the
Program (PGM) and OPM Source Level Debug (OPMSRC) parameters on the STRDBG
command. To start a debug session with an OPM program created with source debug
data, type:
STRDBG PGM(*LIBL/MYOPMPGM) OPMSRC(*YES) DSPMODSRC(*YES)
For more information on ILE
source debugging , see Debugging
ILE Programs.
Any
program can be run in debug mode, but before you can debug it, you must put it
in debug mode. You can place a program in debug mode by specifying it in the
PGM parameter on the STRDBG command or by adding it to the debugging session
with an Add Program (ADDPGM) command. You can specify as many as twenty (20)
programs to be debugged simultaneously in a job. You must have *CHANGE
authority to add a program to debug mode.
If you specified twenty (20)
programs for debug mode (using either the STRDBG or ADDPGM command or both
commands) and you want to add more programs to the debug job, you must remove
some of the previously specified programs. Use the Remove Program (RMVPGM)
command. When debug mode ends, all programs are automatically removed from
debug mode.
When you start debug mode, you
can specify that a program be a default program. By specifying a default
program, you can use any debug command that has the PGM parameter without
having to specify a program name each time a command is used. This is helpful
if you are only debugging one program. For example, in the Add Breakpoint
(ADDBKP) command, you would not specify a program name on the PGM parameter
because the default program is assumed to be the program the breakpoint is
being added to. The default program name must be specified in the list of
programs to be debugged (PGM parameter). If more than one program is listed to
be debugged, you can specify the default program on the DFTPGM parameter. If
you do not, the first program in the list on the PGM parameter on the STRDBG
command is assumed to be the default program.
The default program can be
changed any time during testing by using either the Change Debug (CHGDBG) or
the ADDPGM command.
Note:
If a program that is in debug mode is deleted, re-created, or
saved with storage freed, references made to that program (except a RMVPGM
command) may result in a function check. You must either remove the program
using a RMVPGM command or end debug mode using an ENDDBG command. If you want
to change the program and then debug it, you must remove it from debug mode and
after it is re-created, add it to debug mode (ADDPGM command).
You can use files
in production libraries while you are in debug mode. To prevent database files
in production libraries from being unintentionally changed, you can specify
UPDPROD(*NO) or default to *NO on the STRDBG command. Then, only files in test
libraries can be opened for updating or adding new records. If you want to open
database files in production libraries for updating or adding new records or if
you want to delete members from production physical files, you can specify
UPDPROD(*YES).
You can use this function with
the library list. In the library list for your debug job, you can place a test
library before a production library. You should have copies of the production
files that might be updated by the program being debugged in the test library.
Then, when the program runs, it uses the files in the test library. Therefore,
production files cannot be unintentionally updated.
You can use the Display Debug (DSPDBG)
command to display the call stack, which indicates:
- Which programs are currently being debugged
- The instruction number of the calling instruction
or the instruction number of each breakpoint at which program processing
is stopped
- The program recursion level
- The names of the programs that are in debug mode
but have not been called
A call of a program is the
allocation of automatic storage for the program and the
transfer of machine processing to the program. A series of calls is placed in a
call stack. When a program finishes processing or transfers control, it is
removed from the call stack. For more information about the call stack, see Chapter
3, "Controlling Flow and Communicating between Programs and
Procedures".
A program may be called a number
of times while the first call is still in the call stack. Each call of a
program is a recursion level of the program.
When a call is ended (the program
returns or transfers control), automatic storage is returned to the system.
Notes:
1.
CL programs can be recursive; that is, a CL program can call
itself either directly or indirectly through a program it has called.
2.
Some high-level languages do not allow recursive program calls.
Other languages allow not only programs to be recursive, but also procedures
within a program to be recursive. (In this guide, the term recursion level refers to the number of times the
program has been called in the call stack. A procedure's recursion level is
referred to explicitly as the procedure recursion level.)
3.
All CL commands and displays make use of only the program
qualified name recursion level.
An activation of a program is the
allocation of static storage for the program. An activation is always ended
when one of the following happens:
- The current routing step ends.
- The request that activated the program is
canceled.
- The Reclaim Resources (RCLRSC) command is run
such that the last (or only) call of a program is ended.
In addition, an activation can be
destroyed by actions taken during a program call. These actions are dependent
on the language (HLL or CL) in which the program is written.
When a program is deactivated,
static storage is returned to the system. The language (HLL or CL) in which the
program is written determines when the program is normally deactivated. A CL
program is always deactivated when the program ends.
An RPG/400(R) program is deactivated when the last
record indicator (LR) is set on before the program ends. If there is a return
operation and LR is off, the program is not deactivated.
Normally, if a
program receives an unmonitored escape message, the system sends the function
check message (CPF9999) to the program's program message queue and the program
stops processing. However, HLL program compilers may insert monitors for the
function check message or for messages that may occur in the program. (An
inquiry message is sent to the program messages display.) This allows you to
end the program the way you want. In an interactive debug job, when a function
check occurs, the system provides default handling and gives you control
instead of stopping the program. The system displays the following on the
unmonitored message display:
- The message
- The MI instruction number and HLL statement
identifier, if available, to which the message was sent
- The name and recursion level of the program to
which the message was sent
The following
is an example of an unmonitored message breakpoint display:
+--------------------------------------------------------------------------------+
| Display Unmonitored Message Breakpoint |
| |
| Statement/Instruction . . . . . . . : 440 /0077 |
| Program . . . . . . . . . . . . . . : TETEST |
| Recursion level . . . . . . . . . . : 1 |
| |
| Errors occurred on command. |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| Press Enter to continue. |
| |
| F3=Exit program F10=Command Entry |
| |
+--------------------------------------------------------------------------------+
You can try to isolate the source of the
error by using the testing functions. However, the original request in error is
still stopped at the point where the error occurred. To remove the request in
error from the call stack, you must use the End Request (ENDRQS) command or
press F3 when the unmonitored message breakpoint display is shown. You can let
the usual function check processing continue by pressing the Enter key when the
unmonitored message breakpoint display is shown. If you press F10 to call the
command entry display, you must press F3 to return to the unmonitored message
breakpoint display.
The following shows how a ENDRQS
command works:
Program calls are destroyed when
a ENDRQS command is entered. (In the previous diagram, the program call of PGMA
is destroyed.)
A breakpoint is a
place in a program at which the system stops program processing and gives
control to you at a display station (interactive mode) or to a program
specified on the BKPPGM parameter in the Add Breakpoint (ADDBKP) command (batch
mode).
Use the ADDBKP command to add
breakpoints to the program you want debugged. You can specify up to 10
statement identifiers on the one ADDBKP command. The program variables
specified on an ADDBKP command apply only to the breakpoints specified on that
command. Up to 10 variables can be specified in one ADDBKP command.
You can also specify the name of
the program to which the breakpoint is to be added. If you do not specify the
name of the program that you want the breakpoint added to, the breakpoint is
added to the default program specified on the STRDBG, CHGDBG, or ADDPGM
command.
For more information about
breakpoint commands, see the CL section of the Programming category of the iSeries Information Center.
To add a breakpoint to a program,
specify a statement identifier, which can be:
- A statement label
- A statement number
- A machine interface (MI) instruction number
When you add a breakpoint to a
program, you can also specify program variables whose values or partial values
you want to display when the breakpoint is reached. These variables can be
shown in character or hexadecimal format.
Program processing stops at a
breakpoint before the instruction is processed. For an
interactive job, the system displays what breakpoint the program has stopped at
and, if requested, the values of the program variables.
In high-level language programs,
different statements and labels may be mapped to the same internal instruction.
This happens when there are several inoperable statements (such as DO and
ENDDO) following one another in a program. You can use the IRP list to
determine which statements or labels are mapped to the same instruction.
The result of different
statements being mapped to the same instruction is that a breakpoint being
added may redefine a previous breakpoint that was added for a different
statement. When this occurs, a new breakpoint replaces the previously added
breakpoint, that is, the previous breakpoint is removed and the new breakpoint
is added. After this information is displayed, you can do any of the following:
- End the most recent request by pressing F3.
- Continue program processing by pressing Enter.
- Go to the command entry display at the next request level by
pressing F10. From this display, you can:
- Enter any CL command that can be used in an
interactive debug environment. You may display or change the values of
variables in your program, add or remove programs from debug mode, or
perform other debug commands.
- Continue processing the program by entering the
Resume Breakpoint (RSMBKP) command.
- Return to the breakpoint display by pressing F3.
- Return to the command entry display at the
previous request level by entering the End Request (ENDRQS) command.
For a batch job, a breakpoint program can be called when a
breakpoint is reached. You must create this breakpoint program to handle the
breakpoint information. The breakpoint information is passed to the breakpoint
program. The breakpoint program is another program such as a CL program that
can contain the same commands (requests for function) that you would have
entered interactively for an interactive job. For example, the program can
display and change variables or add and remove breakpoints. Any function valid
in a batch job can be requested. When the breakpoint program completes
processing, the program being debugged continues.
A message is recorded in the job
log for every breakpoint for the debug job.
The following ADDBKP commands add
breakpoints to the program CUS310. CUS310 is the default program, so it does
not have to be specified. The value of the variable &ARBAL is shown when
the second breakpoint is reached.
ADDBKP STMT(900)
ADDBKP STMT(2200) PGMVAR('&ARBAL')
Note:
A CL variable must be entered with surrounding apostrophes.
The source for CUS310 looks like
this:
5728PW1 R01M00 880101 SEU SOURCE LISTING
SOURCE FILE . . . . . . . QGPL/QCLSRC
MEMBER . . . . . . . . . CUS310
SEQNBR*...+... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...
100 PGM PARM(&NBRITEMS &ITEMPRC &PARBAL &PTOTBAL)
200 DCL VAR(&PARBAL) TYPE(*DEC) LEN(15 5) /* INPUT AREA INV BALANCE */
300 DCL VAR(&PTOTBAL) TYPE(*DEC) LEN(15 5) /* INPUT TOTAL INV BALANCE*/
400 DCL VAR(&NBRITEMS) TYPE(*DEC) LEN(15 5) /* NUMBER OF ITEMS */
500 DCL VAR(&ITEMPRC) TYPE(*DEC) LEN(15 5) /* PRICE OF THE ITEM */
600 DCL VAR(&ARBAL) TYPE(*DEC) LEN(5 2) /* AREA INVENTORY BALANCE */
700 DCL VAR(&TOTBAL) TYPE(*DEC) LEN(5 2) /* TOTAL INVENTORY BALANCE*/
800 DCL VAR(&TOTITEM) TYPE(*DEC) LEN(5 2) /* TOTAL PRICE OF ITEMS */
900 CHGVAR VAR(&ARBAL) VALUE(&PARBAL)
1000 CHGVAR VAR(&TOTBAL) VALUE(&PTOTBAL)
1100 IF COND(&NBRITEMS *EQ 0) THEN(DO)
1200 SNDPGMMSG MSG('The number of items is zero. This item +
1300 should be ordered.') TOMSGQ(INVLIB/INVQUEUE)
1400 GOTO CMDLBL(EXIT)
1500 ENDDO
1600 CHGVAR VAR(&TOTITEM) VALUE(&NBRITEMS * &ITEMPRC)
1700 IF COND(&NBRITEMS *GT 50) THEN(DO)
1800 SNDPGMMSG MSG('Too much inventory for this item.') +
1900 TOMSGQ(INVLIB/INVQUEUE)
2000 ENDDO
2100 CHGVAR VAR(&ARBAL) VALUE(&ARBAL + &TOTITEM)
2200 IF COND(&ARBAL *GT 1000) THEN(DO)
2300 SNDPGMMSG MSG('The area has too much money in +
2400 inventory.') TOMSGQ(INVLIB/INVQUEUE)
2500 ENDDO
2600 CHGVAR VAR(&TOTBAL) VALUE(&TOTBAL + &TOTITEM)
2700 EXIT: ENDPGM
The following is displayed as a result of
reaching the first breakpoint:
+--------------------------------------------------------------------------------+
| Display Breakpoint |
| |
|Statement/Instruction . . . . . . . . . : 900 /0009 |
|Program . . . . . . . . . . . . . . . . : CUS310 |
|Recursion level . . . . . . . . . . . . : 1 |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|Press Enter to continue. |
| |
|F3=Exit program F10=Command entry |
| |
+--------------------------------------------------------------------------------+
The following is displayed as a
result of reaching the second breakpoint:
+--------------------------------------------------------------------------------+
| Display Breakpoint |
| |
|Statement/Instruction . . . . . . . . . : 2200 /0022 |
|Program . . . . . . . . . . . . . . . . : CUS310 |
|Recursion level . . . . . . . . . . . . : 1 |
|Start position . . . . . . . . . . . . : 1 |
|Format . . . . . . . . . . . . . . . . : *CHAR |
|Length . . . . . . . . . . . . . . . . : *DCL |
| |
|Variable . . . . . . . . . . . . . . . : &ARBAL |
| Type . . . . . . . . . . . . . . . . : PACKED |
| Length . . . . . . . . . . . . . . . : 5 2 |
| '610.00' |
| |
| |
| |
| |
| |
| |
| |
|Press Enter to continue. |
| |
|F3=Exit program F10=Command entry |
| |
+--------------------------------------------------------------------------------+
The variable &ARBAL is shown.
(Note that the value of &ARBAL will vary depending on the parameter values
passed to the program.) You can press F10 to display the command entry display
so that you could change the value of the variable &ARBAL to alter your
program's processing. You use the Change Program Variable (CHGPGMVAR) command
to change the value of a variable.
You may add a conditional breakpoint to a program that is being
debugged. Use the Add Breakpoint (ADDBKP) command to specify the statement and
condition. If the condition is met, the system stops the program processing at
the specified statement.
You may specify a skip value on
the ADDBKP command. A skip
value is a number that
indicates how many times a statement should be processed before the system
stops the program. For example, to stop a program at statement 1200 after the
statement has been processed 100 times, enter the following command:
ADDBKP STMT(1200) SKIP(100)
If you specify multiple
statements when the SKIP parameter is specified, each statement has a separate
count. The following command causes your program to stop on statement 150 or
200, but only after the statement has processed 400 times:
ADDBKP STMT(150 200) SKIP(400)
If statement 150 has processed
400 times but statement 200 has processed only 300 times, then the program does
not stop on statement 200.
If a statement has not processed
as many times as was specified on the SKIP parameter, the Display Breakpoint
(DSPBKP) command can be used to show how many times the statement was
processed. To reset the SKIP count for a statement to zero, enter the
breakpoint again for that statement.
You can specify a more general
breakpoint condition on the ADDBKP command. This expression uses a program
variable, an operator, and another variable or constant as the operands. For
example, to stop a program at statement 1500 when variable &X is greater
than 1000, enter the following command:
ADDBKP STMT(1500) PGMVAR('&X') BKPCOND(*PGMVAR1 *GT 1000)
The BKPCOND parameter requires
three values:
- In the example, the first value specifies the
first variable specified on the PGMVAR parameter. (To specify the third
variable, you would use *PGMVAR3.)
- The second value must be an operator. For a list
of all valid operators, see the CL section of the Programming category of the iSeries Information Center.
- The third value may be a constant or another
variable. A constant may be a number, character string, or bit string, and
must be the same type as the program variable specified in the first
value.
The SKIP and BKPCOND parameters
can be used together to specify a complex breakpoint condition. For example, to
stop a program on statement 1000 after the statement has been processed 50
times and only when the character string &STR is TRUE, enter the following command:
ADDBKP STMT(1000) PGMVAR('&STR') SKIP(50)
BKPCOND(*PGMVAR1 *EQ 'TRUE ')
To remove breakpoints
from a program, use the Remove Breakpoint (RMVBKP) command. To remove a
breakpoint you must specify the statement number of the statement for which the
breakpoint has been defined.
A trace is the
process of recording the sequence in which the statements in a program are
processed. A trace differs from a breakpoint in that you are not given control
during the trace. The system records the traced statements that were processed.
However, the trace information is not automatically displayed when the program
completes processing. You must request the display of trace information using
the Display Trace Data (DSPTRCDTA) command. The display shows the sequence in
which the statements were processed and, if requested, the values of the
variables specified on the Add Trace (ADDTRC) command.
Adding a trace consists of
specifying what statements are to be traced and, if you want, the names of
program variables. Before a traced statement processes, the value of the
variable is recorded. Also, you can specify that the values of the variables
are to be recorded only if they have changed from the last time a traced
statement was processed. These variables can be displayed in character format
or hexadecimal format.
To specify which statements are
to be traced, you can specify:
- The statement identifier at which the trace is to
start and the statement identifier at which the trace is to stop
- That all statements in the program are to be
traced
- A single statement identifier of a statement to
be traced
On the STRDBG or CHGDBG command, you can
specify how many statement traces can be recorded for a job and what action the
system should take when the maximum is reached. When the maximum is reached,
the system performs one of the following actions (depending on what you
specify):
- For an interactive job, either of the following
can be done:
- Stop the trace (*STOPTRC). Control is given to
you (a breakpoint occurs), and you can remove some of the trace
definitions (RMVTRC command), clear the trace data (CLRTRCDTA command),
or change the maximum (MAXTRC parameter on the CHGDBG command).
- Continue the trace (*WRAP). Previously recorded
trace data is overlaid with trace data recorded after this point.
- For a batch job, either of the following can be
done:
- Stop the trace (*STOPTRC). The trace definitions
are removed and the program continues processing.
- Continue the trace (*WRAP). Previously recorded
trace data is overlaid with trace data recorded after this point.
You can change the maximum and
the default action any time during the debug job using the Change Debug
(CHGDBG) command. However, the change does not affect traces that have already
been recorded.
You can only specify a total of
five statement ranges for a single program at any one time, which is a total
taken from all the Add Trace (ADDTRC) commands for the program. In addition,
only 10 variables can be specified for each statement range.
In high-level language programs,
different statements and labels may be mapped to the same internal instruction.
This happens when there are several inoperable statements (such as DO, END)
following one another in a program. You can use the IRP list to determine which
statements or labels are mapped to the same instruction.
When you specify CL variables,
you must enclose the & and the variable name in single apostrophes. For
example:
ADDTRC PGMVAR('&IN01')
When you specify a statement
range, the source statement number for the stop statement is ordinarily larger
than the number for the start statement. Tracing, however, is performed with
machine interface (MI) instructions, and some compilers (notably RPG/400)
generate programs in which the order of MI instructions is not the same as the
order of the source statements. Therefore, in some cases, the MI number of the
stop statement may not be larger than the MI number of the start statement, and
you will receive message CPF1982.
When you receive this message,
you should do one of the following:
- Trace all statements in the program.
- Restrict a statement range to one specification.
- Use MI instruction numbers gotten from an
intermediate representation of a program (IRP) list of the program. (See Debugging
at the Machine Interface Level.)
The following Add Trace (ADDTRC)
command adds a trace to the program CUS310. CUS310 is the default program, so
it does not have to be specified. The value of the variable &TOTBAL is
recorded only if its value changes between the times each traced statement is
processed.
ADDTRC STMT((900 2700)) PGMVAR('&TOTBAL') OUTVAR(*CHG)
The
following displays result from this trace and are displayed using the Display
Trace Data (DSPTRCDTA) command. Note that column headers are not supplied for
all displays.
+--------------------------------------------------------------------------------+
| Display Trace Data |
| |
| Statement/ |
|Program Instruction Recursion level Sequence number |
|CUS310 900 1 1 |
| |
| Start position . . . . . . . . . . . . : 1 |
| Length . . . . . . . . . . . . . . . . : *DCL |
| Format . . . . . . . . . . . . . . . . : *CHAR |
| |
| Variable . . . . . . . . . . . . . . . : &TOTBAL |
| Type . . . . . . . . . . . . . . . . : PACKED |
| Length . . . . . . . . . . . . . . . : 5 2 |
| ' .00' |
| |
| Statement/ |
|Program Instruction Recursion level Sequence number |
|CUS310 1000 1 2 |
|CUS310 1100 1 3 + |
| |
|Press Enter to continue. |
| |
|F3=Exit F12=Cancel |
| |
+--------------------------------------------------------------------------------+
+--------------------------------------------------------------------------------+
| Display Trace Data |
| |
| |
| Start position . . . . . . . . . . . . : 1 |
| Length . . . . . . . . . . . . . . . . : *DCL |
| Format . . . . . . . . . . . . . . . . : *CHAR |
| |
|*Variable . . . . . . . . . . . . . . . : &TOTBAL |
| Type . . . . . . . . . . . . . . . . : PACKED |
| Length . . . . . . . . . . . . . . . : 5 2 |
| ' 1.00' |
| |
| Statement/ |
|Program Instruction Recursion level Sequence number |
|CUS310 1600 1 4 |
|CUS310 1700 1 5 |
|CUS310 2100 1 6 |
|CUS310 2200 1 7 |
|CUS310 2600 1 8 + |
| |
|Press Enter to continue. |
| |
|F3=Exit F12=Cancel |
| |
+--------------------------------------------------------------------------------+
+--------------------------------------------------------------------------------+
| Display Trace Data |
| |
|CUS310 2700 1 9 |
| |
| Start position . . . . . . . . . . . . : 1 |
| Length . . . . . . . . . . . . . . . . : *DCL |
| Format . . . . . . . . . . . . . . . . : *CHAR |
| |
|*Variable . . . . . . . . . . . . . . . : &TOTBAL |
| Type . . . . . . . . . . . . . . . . : PACKED |
| Length . . . . . . . . . . . . . . . : 5 2 |
| ' 2.00' |
| |
| |
| |
| |
| |
| |
| |
| |
|Press Enter to continue. |
| |
|F3=Exit F12=Cancel |
| |
+--------------------------------------------------------------------------------+
Instruction Stepping
You can step through the instructions of a
program by using the STRDBG or CHGDBG commands and setting the MAXTRC parameter
to 1 and the TRCFULL parameter to *STOPTRC. When you specify a trace range
(ADDTRC command) and the program processes an instruction within that range, a
breakpoint display with an error message appears. If you press Enter, another
breakpoint display with the same error message appears for the next instruction
processed in the trace range. When tracing is completed, the trace data
contains a list of the instructions traced. You can display this data by
entering the Display Trace Data (DSPTRCDTA) command.
Breakpoints can be
used within a trace range. At a breakpoint within a trace, you can display the
trace data (DSPTRCDTA command) to determine if you need to take some action.
The trace data is recorded before the breakpoint occurs. The trace information
contains the value of any variables before the statement was processed.
On the DSPTRCDTA command, you can specify whether the trace
information is removed from the system or left on the system after the
information is displayed. If you leave the trace information on the system, any
other traces are added to it. The information remains on the system (unless
removed) until the debug job ends or the ENDDBG command is submitted. You can
also use the Clear Trace Data (CLRTRCDTA) command to remove trace information
from the system.
The Remove Trace
(RMVTRC) command removes all or some of the ranges specified in one or more Add
Trace (ADDTRC) commands. Removing a trace range consists of specifying the
statement identifiers used on the RMVTRC command, or specifying that all ranges
be removed.
You can use the STMT parameter on the RMVTRC command to specify:
- All HLL statements and/or machine instructions in
the specified program are not to be traced regardless of how the trace was
defined by the ADDTRC command.
- The start and stop trace location of the HLL
statements and/or system instructions to be removed.
The RMVPGM and ENDDBG commands also remove traces, but they also
remove the program from debug mode.
In debug mode, you can display testing
information that lets you review how you have set up your debug job. You can
display what programs are in debug mode and what breakpoints and traces have
been defined for those programs. In addition, you can display the status of the
programs in debug mode.
You can use the following
commands to display testing information:
- Display Debug (DSPDBG), which displays the
current call stack and the names of the programs that are in debug mode
and indicates the following:
- Which are stopped at a breakpoint
- Which are currently called
- The request level of those that are called
- Debug options selected for the debug job
- Display Breakpoint (DSPBKP), which displays the
locations of breakpoints that are currently defined in a program.
- Display Trace (DSPTRC), which displays the
statements or statement ranges that are currently defined in a program.
When you are at a
breakpoint, you can display the values of program variables. You can have this
done automatically on the breakpoint display by specifying the variable names
on the ADDBKP command, or you can enter the Display Program Variable
(DSPPGMVAR) command at the breakpoint by pressing F10 to show the command entry
display. Only 10 variables can be specified on one DSPPGMVAR command. For
character and bit variables, you can tell the system to begin displaying the
value of the variable starting at a certain position and for a specified length.
Variables can be displayed in either character or hexadecimal format.
Notes:
1.
If you specify an array variable, you can do one of the following:
1.
Specify the subscript values of the array element you want to
display. The subscript values can either be integer values or the names of
numeric variables in the program.
2.
Display the entire array by not entering any subscripts.
3.
Display a single-dimension cross-section of the array by
specifying values for all subscripts except one, and an asterisk for that one subscript
value.
2.
Variable names can be specified as simple or qualified names, but
must be placed between apostrophes. A qualified name can be specified in either
of two ways:
1.
Variable names alternating with the special separator words OF or
IN, ordered from lowest to highest qualification level. A blank must separate
the variable name and the special separator word.
2.
Variable names separated by periods, ordered from highest to
lowest qualification level.
The following DSPPGMVAR command
displays the variable ARBAL used in the program CUS310. CUS310 is the default
program, so it does not have to be specified. The entire value is to be
displayed in character format.
DSPPGMVAR PGMVAR('&ARBAL')
The resulting display looks like
this:
+--------------------------------------------------------------------------------+
| Display Program Variables |
| |
|Program . . . . . . . . . . . . . . . . : CUS310 |
|Recursion level . . . . . . . . . . . . : 1 |
|Start position . . . . . . . . . . . . : 1 |
|Format . . . . . . . . . . . . . . . . : *CHAR |
|Length . . . . . . . . . . . . . . . . : *DCL |
| |
|Variable . . . . . . . . . . . . . . . : &ARBAL |
| Type . . . . . . . . . . . . . . . . : PACKED |
| Length . . . . . . . . . . . . . . . : 5 2 |
| '610.00' |
| |
| |
| |
| |
| |
| |
| |
| |
|Press Enter to continue. |
| |
|F3=Exit F12=Cancel |
| |
+--------------------------------------------------------------------------------+
Some HLLs allow variables to be
based on a user-specified pointer variable (HLL pointer). If you do not specify
an explicit pointer for a based variable, the pointer specified in the HLL
declaration (if any) is used. You must specify an explicit basing pointer if
one was not specified in the HLL declaration for the based variable. The PGMVAR
parameter allows you to specify up to five explicit basing pointers when
referring to a based variable. When multiple basing pointers are specified, the
first basing pointer specified is used to locate the second basing pointer, the
second one is then used to locate the third, and so forth. The last pointer in
the list of basing pointers is used to locate the primary variable.
To
change the value of a program variable, use the Change Program Variable
(CHGPGMVAR), the Change HLL Pointer (CHGHLLPTR), or the Change Pointer (CHGPTR)
command. Changing the value of a program variable consists of specifying the
variable name and a value that is compatible with the data type of the
variable. For example, if the variable is character type, you must enter a
character value.
When changing the value of
variables, you should be aware of whether the variable is an automatic variable
or a static variable. The difference between the two is in the storage for the
variables. For automatic variables, the storage is associated with the call of
the program. Every time a program is called, a new copy of the variable is
placed in automatic storage. A change to an automatic variable remains in
effect only for the program call the change was made in.
Note:
In some languages, the definition of a call is made at the
procedure level and not just at the program level. For these languages, storage
for automatic variables is associated with the call of the procedure. Every
time a procedure is called, a new copy of the variable is gotten. A change to
an automatic variable remains in effect only while that procedure is called.
Only the automatic variables in the most recent procedure call can be changed.
The RCRLVL (recursion level) parameter on the commands applies only on a
program basis and not on a procedure basis.
For static variables, the storage
is associated with the activation. Only one copy of a static variable exists in
storage no matter how many times a program is called. A change to a static
variable remains in effect for the duration of the activation.
To determine if a program
variable is a static or an automatic variable, request an intermediate
representation of a program (IRP) list (*LIST and *XREF on the GENOPT
parameter) when the program containing the variables is created.
When changing a variable that is
an array, you must specify one element of the array. Consequently, you must
specify the subscript values for the array element you want to change.
You may want
to use a separate job to debug programs running in another job for one of the
following reasons:
- Batch jobs can be debugged by an interactive job.
- An interactive job can be debugged from another interactive job.
This allows one display to show debug information without interrupting the
application program display.
- An interactive or batch job that is looping can be interrupted and
put into debug mode.
Using a separate job to debug another
batch job submitted to the job queue allows you to put the batch job into debug
mode and to set breakpoints and traces before the job starts to process. Use
the following steps to debug batch jobs to be submitted to a job queue:
1.
Submit the batch job using the Submit Job (SBMJOB) command or a
program that automatically submits the job with HOLD(*YES).
2. SBMJOB HOLD(*YES)
3.
Determine the qualified job name (number/user/name) that is
assigned to the job using the Work with Submitted Jobs (WRKSBMJOB) command or
the Work with Job Queues (WRKJOBQ) command. The SBMJOB command also displays
the name in a completion message when the command finishes processing.
The
WRKJOBQ (Work With Job Queue) command displays all the jobs waiting to start in
a particular job queue. You can show the job name from this display by
selecting option 5 for the job.
4.
Enter the Start Service Job (STRSRVJOB) command from the display
you plan to use to debug the batch job as follows:
5. STRSRVJOB JOB(qualified-job-name)
6.
Enter the STRDBG command and provide the names of all programs to
be debugged. No other debug commands can be entered while the job is waiting on
the job queue.
7.
Use the Release Job Queue (RLSJOBQ) command to release the job
queue. A display appears when the job is ready to start, indicating that you
may begin debugging the job. Press F10 to show the Command Entry display.
8.
Use the Command Entry display to enter any debug commands, such as
the Add Breakpoint (ADDBKP) or Add Trace (ADDTRC) commands.
9.
Press F3 to leave the Command Entry display, and then press Enter
to start the batch job.
10. When the job stops at a
breakpoint, you see the normal breakpoint display. When the job finishes, you
cannot add breakpoints and traces, or display or change variables. However, you
can display any trace data using the Display Trace Data (DSPTRCDTA) command.
11. If you wish to debug another
batch job, first end debugging using the End Debug (ENDDBG) command and then
end servicing the job using the End Servicing Job (ENDSRVJOB) command.
Some jobs started on the system are not
submitted to a job queue. These jobs cannot be stopped before they start
running but they can usually be debugged. To debug jobs not started from a job
queue, do the following:
1.
Rename the program that is called when the job starts. For
example, if the job runs program CUST310, you can rename this program to
CUST310DBG.
2.
Create a small CL program with the same name as the original
program (before the program was renamed). In the small CL program, use the
Delay Job (DLYJOB) command to delay for one minute and then use the CALL
command to call the renamed program.
3.
Allow the batch job to start to force the CL program to be delayed
for one minute.
4.
Use the Work with Active Jobs (WRKACTJOB) command to find the
batch job that is running. When the display appears, enter option 5 next to the
job to obtain the qualified job name.
5.
Enter the Start Service Job (STRSRVJOB) command as follows:
6. STRSRVJOB JOB(qualified-job-name)
7.
Enter STRDBG and any other debug commands, such as the Add
Breakpoint (ADDBKP) or Add Trace (ADDTRC) command. Proceed with debugging as
usual.
You can debug
a job that is already running if you know what statements the job will run. For
example, you may want to debug a running program if the job is looping or the
job has not yet run a program that is to be debugged. The following steps allow
you to debug a running job:
1.
Use the Work with Active Jobs (WRKACTJOB) command to find the job
that is running. When the display appears, enter option 5 next to the job to
obtain the qualified job name.
2.
Enter the Start Service Job (STRSRVJOB) command as follows:
3. STRSRVJOB JOB(qualified-job-name)
4.
Enter the Start Debug (STRDBG) command. (Entering the command does
not stop the job from running.)
Note:
You can use the Display Debug (DSPDBG) command to show the call
stack. However, unless the program is stopped for some reason, the stack is
correct only for an instant, and the program continues to run.
5.
If you know a statement to be run, enter the Add Breakpoint
(ADDBKP) command to stop the job at the statement.
If you
do not know what statements are being run, do the following:
a.
Enter the Add Trace (ADDTRC) command.
b.
After a short time, enter the Remove Trace (RMVTRC) command to
stop tracing the program.
c.
Enter the Display Trace Data (DSPTRCDTA) command to show what
statements have processed. Use the trace data to determine which data
statements to process next (for example, statements inside a program loop).
d.
Enter the Add Breakpoint (ADDBKP) command to stop the job at the
statement.
6.
Enter the desired debug commands when the program is stopped at a
breakpoint.
You can debug a job from another display, whether the job is
running or waiting at a menu or command entry display. To debug another
interactive job, do the following:
1.
Determine the qualified job name of the job to be debugged. To
determine the name, either enter the Display Job (DSPJOB) command from the
display of the job to be debugged, or use the Work with Active Jobs (WRKACTJOB)
command.
2.
Enter the Start Service Job (STRSRVJOB) command using the
qualified job name.
3.
Enter the Start Debug (STRDBG) command and any other debug
commands desired. If the job is already running, you may need to enter the
Display Debug (DSPDBG) command to determine what statement in the program is
processing.
When the job being debugged is
stopped at a breakpoint, the display station is locked.
Although most
jobs can be debugged from another job, you must take the following into
consideration:
- A job being debugged cannot be held or suspended
(for example, when running another group job or a secondary job).
- When servicing another job with the Start Service
Job (STRSRVJOB) command, you cannot also debug the job doing the
servicing. All debug commands apply only to the job being serviced. To
debug the job doing the servicing, you must either end the servicing of
the other job, or have another job service and debug it.
- Debug commands operate on another job, even if
that job is not stopped at a breakpoint. For example, if you are debugging
a running job and you enter the Display Program Variable (DSPPGMVAR)
command, the variable you specify is shown. Since the job continues to
run, the value of the variable may change soon after the command is
entered.
- A job being debugged must have enough priority to
respond to debug commands. If you are debugging a batch job with a low
priority and that job gets no processing time, then any debug command you
issue waits for a response from the job. If the job does not respond, the
command ends and an error message is displayed.
- You cannot service and debug a job that is
debugging itself. However, you can service and debug a job that is
servicing and debugging another job.
To debug your programs at the machine interface (MI) level, you
can specify an MI object definition vector (ODV) number for the PGMVAR
parameter of a command and MI instruction numbers for the STMT parameter of a command. For a breakpoint,
the system stops at the MI instruction number just as it would at an HLL
statement number. You must always precede the ODV or MI instruction number with
a slash (/) and enclose it in apostrophes (for example, '/1A')
to signal to the system that you are debugging at the MI level.
The ODV and MI instruction
numbers can be obtained from the IRP listing produced by most high-level
language compilers. Use the *LIST value of the GENOPT parameter to produce the
IRP listing at program creation time.
Note:
When you debug at the machine interface level, only the
characteristics that are defined at the machine interface level are available;
the HLL characteristics that are normally passed to the test environment are
not available. These HLL characteristics may include: the variable type, number
of fractional digits, length, and array information. For example, a numeric
variable in your HLL program may be displayed without the correct decimal
alignment or possibly as a character string.
To debug a program, you must have *CHANGE
authority to that program. The *CHANGE authority available by adopting another
user's profile is not considered when determining whether a user has authority
to debug a program. This prevents users from accessing program data in debug
mode by adopting another user's profile.
Additionally, when you are at a
user-defined breakpoint of a program that you are debugging with adopted user
authority, you have only the authority of your user profile and not the adopted
profile authority. You do not have authorities adopted by prior program calls
for all breakpoints whether they are added by the Add Breakpoint (ADDBKP)
command or are caused by an unmonitored escape message.
Using COPY,
SAVE, RESTORE, CRTDUPOBJ, and CHKOBJITG while Debugging
Breakpoints or statement traces
may be temporarily removed from a program while the debug
function is running if you use certain control language (CL) commands to
specify your library or program. Breakpoints and statement traces arerestored when the CL command completes running.
A CPD190A message is in the job log when the breakpoints or traces are removed;
another CPD190A message is in the job log when the breakpoints and statement
traces are restored.
Breakpoints or statement traces
may be temporarily removed from a program when you use the
following CL commands to specify your library:
CHKOBJITG
|
CPY
CPYLIB
|
CPROBJ
CRTDUPOBJ
|
RSTLIB
RSTOBJ
|
SAVLIB
SAVOBJ
SAVSYS
SAVCHGOBJ
|
Note:
When the CL commands are running on your program, you may not be
able to add breakpoints or add traces to the program. If you enter the Add
Breakpoint (ADDBKP) command or the Add Trace (ADDTRC) command when any of the
commands are running on your program, you will receive error message CPF7102.