Friday, November 27, 2015

Debugging Programs


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

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.

Debug Commands

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.

Preparing a Program Object for a Debug Session

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

Using a Root Source 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.

Using a Listing View

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)

Using a Statement View

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)

Starting the ILE Source Debugger

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)

Adding Program Objects to a Debug Session

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.

Removing Program Objects from a Debug Session

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.

Viewing the Program Source

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.

Changing a Module Object

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.

Changing the View of a Module Object

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.

Setting and Removing Breakpoints

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.

Setting and Removing Unconditional Breakpoints

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.

Setting and Removing Conditional Breakpoints

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
Using the Work with Breakpoints Display
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.
Using the BREAK and CLEAR 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.
National Language Sort Sequence (NLSS)
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>.
Conditional Breakpoint Examples
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.

Removing All Breakpoints

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.

Stepping through the Program Object

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

Using F10 or F22 on the Display Source Display

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.

Using the STEP Debug Command

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.

Step Over and Step Into

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.

Stepping over Program Objects

You can step over program objects by using:
  • F10 (Step) on the Display Module Source display
  • The STEP OVER debug command

Using F10(Step)

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.

Using the Step Over Debug Command

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.

Stepping into Program Objects

You can step into program objects by using:
  • F22 (Step into) on the Display Module Source display
  • The STEP INTO debug command

Using F22(Step Into)

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.

Using the Step Into Debug Command

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.

Displaying Variables

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.

Using F11(Display Variable)

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.

Display logical variable example

CL declarations:   DCL    VAR(&LGL1) TYPE(*LGL) VALUE('1')
 
 
Debug command:     EVAL &LGL1
 
Result:            &LGL1 = '1'
 
 

Display character variable examples

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.

Display decimal variable example

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

Displaying Variables as Hexadecimal Values

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     ............

Changing the Value of Variables

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'

Change logical variable examples

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'
 

Change character variable examples

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.

Change decimal variable examples

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
 

Attributes of a Variable Examples

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

Equating a Name with a Variable, Expression, or Command

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.

Source Debug National Language Support for ILE CL

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.

Working with *SOURCE View

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.

Debugging OPM Programs

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.

Debug Mode

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.

Adding Programs to Debug Mode

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).

Preventing Updates to Database Files in Production Libraries

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.

The Call Stack

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.

Program Activations

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.

Handling Unmonitored Messages

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.)

Breakpoints

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).

Adding Breakpoints to Programs

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.

Conditional Breakpoints

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 ')

Removing Breakpoints from Programs

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.

Traces

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 Traces to Programs

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.

Using Breakpoints within Traces

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.

Removing Trace Information from the System

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.

Removing Traces from Programs

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.

Display Functions

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.

Displaying the Values of Variables

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.

Changing the Values of Variables

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.

Using a Job to Debug Another Job

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.

Debugging Batch Jobs Submitted to a Job Queue

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.

Debugging Batch Jobs Not Started from Job Queues

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.

Debugging a Running Job

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.

Debugging Another Interactive Job

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.

Considerations When Debugging One Job from Another Job

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.

Debugging at the Machine Interface Level

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.

Security Considerations

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.

No comments:

Post a Comment