When it comes to tracking down a problem in your program, tracing the actual program code while the program is running is the quickest method for finding the problem. This method, known as source-level debugging, has been around for years.
With a source-level debugger, the program source statements are displayed on your workstation as the program is running. By stopping at selected statements (setting breakpoints) you can control how much of your program runs before you examine the program by displaying the values of the program's variables.
When the program reaches a breakpoint, the program stops and displays the statement to which the breakpoint has been assigned and the statements surrounding it. This way you can easily examine and change the variables used in that particular section of code. Of course, you can page or jump through the program to access other variables, or you can step through single statements or groups of statements, examining program variables along the way.
Unfortunately for AS/400 programmers, source-level debugging wasn't available from IBM until recently. Unless you were willing to purchase a third-party source debugger, you were faced with using the very limited OS/400 system debugger. That debugger required that you have the most recent source listing of a program before you could use it effectively. And even then it was cumbersome.
However, the good news is that, with V3R1, IBM has given you a source-level debug function for ILE programs and several other significant enhancements to the system debugger.
Introducing ILE Source Debugger
All of the ILE languages on the AS/400 have a new debug interface that displays a program's source statements during a debug session. The ILE source debugger offers you these options.
o View the program source. o Set and remove conditional and unconditional breakpoints. o Step through a specified number of statements. o Display or change the value of fields, structures, and arrays. o Equate shorthand names for fields, expressions, or debug commands.
The source-level debug functions of the system debugger are only available to ILE programs. However, you can perform source-level debugging for Original Program Model (OPM) RPG, COBOL, and CL programs with the Interactive Source Debugger (ISDB). ISDB is a free component of the Application Development ToolSet/400 (ADTS/400) beginning with V3R1. For more information about ISDB see "IBM's New Source-Level Debugger," MC, September 1994.
Some ILE Background
Before you can understand the ILE source debugger, you need to know a little about ILE. Most of you know the basics, but, for those who don't, the following background material will help you understand the ILE source debugger.
The notion of modularity in programming has been around for some time. Ideally, an application would be made up of small, single-purpose programs that could call each other when a certain function was required. Of course, smaller programs mean more programs and more programs calling other programs (external program calls).
Before ILE, external program calls could only be performed one way- dynamically. Dynamic calls occur at run time and require significant system overhead. Therefore, on the AS/400 a programmer could only break his programs down so much before the performance of the application would degrade beyond a tolerable level. This is one reason most AS/400 programs tend to be large.
With ILE, you can get around the performance issue of dynamic calls by linking your programs together as if they were one program. ILE languages utilize an intermediate object that is created from program source code. This intermediate object is known as a module object (object type *MODULE) and is not executable. One or more modules are linked together to create the program object (object type *PGM). Any module, no matter what language is used to create it, can be linked to another module. Combining modules into a single executable program is called binding.
Modules within a program can be called by one another just like programs call each other. Calls to modules are known as bound calls. The ILE RPG operation for a bound call is CALLB. The difference between a bound call and a dynamic call is that having modules call one another within a program is much faster than performing external program calls dynamically at run time. Essentially, an ILE programmer can break an application into smaller, simpler, and more maintainable pieces without concern about performance degradation. For more information on ILE, see "An Introduction to Program Binding," MC, August 1994, or "The Integrated Language Environment," MC, May 1993.
Now that you understand a little about modules, you can better understand the ILE debugger.
A Closer Look
With the ILE source debugger, you actually debug at the module level, not the program level. Unlike OPM programs which store observability information in the program, ILE programs store observability in a program's modules. ILE observability is now split into two parts-debug information and the program template. 1 illustrates how ILE observability is stored.
With the ILE source debugger, you actually debug at the module level, not the program level. Unlike OPM programs which store observability information in the program, ILE programs store observability in a program's modules. ILE observability is now split into two parts-debug information and the program template. Figure 1 illustrates how ILE observability is stored.
To start the debugger, use the same Start Debug (STRDBG) command you're used to using. The system determines whether the program you want to debug is an OPM or ILE program. If it's an OPM program, the debugger works just as it used to and you can use the traditional debug commands, such as Add Breakpoint (ADDBKP), Add Trace (ADDTRC), and so on. If the program is an ILE program and you created its modules with the appropriate debug view (see the next section, "One Preliminary Step"), you'll be presented with the Display Module Source display (see 2). As you can see, the program source statements are displayed. This initial display allows you to set your breakpoints. Unfortunately, you can't start the program from the initial display; you must get to a command line to start it. If you defined any breakpoints, the Display Module Source screen will reappear when the program is called, the source code will be positioned at the first breakpoint.
To start the debugger, use the same Start Debug (STRDBG) command you're used to using. The system determines whether the program you want to debug is an OPM or ILE program. If it's an OPM program, the debugger works just as it used to and you can use the traditional debug commands, such as Add Breakpoint (ADDBKP), Add Trace (ADDTRC), and so on. If the program is an ILE program and you created its modules with the appropriate debug view (see the next section, "One Preliminary Step"), you'll be presented with the Display Module Source display (see Figure 2). As you can see, the program source statements are displayed. This initial display allows you to set your breakpoints. Unfortunately, you can't start the program from the initial display; you must get to a command line to start it. If you defined any breakpoints, the Display Module Source screen will reappear when the program is called, the source code will be positioned at the first breakpoint.
You'll do most of your debugging from the Display Module Source screen. As shown in 2, there is a command line at the bottom of the display. This is a debug command line where you can enter special debug commands. For example, you can enter the Attributes (ATTR) command to display the attributes of a variable, the Breakpoint (BREAK) command to set an unconditional or a conditional breakpoint, or the Evaluate (EVAL) command to display a variable's value. You can also use the HELP command to display a list of valid commands with brief descriptions. 3 contains a complete list of the ILE debugger commands, the command abbreviations, and a summarized description.
You'll do most of your debugging from the Display Module Source screen. As shown in Figure 2, there is a command line at the bottom of the display. This is a debug command line where you can enter special debug commands. For example, you can enter the Attributes (ATTR) command to display the attributes of a variable, the Breakpoint (BREAK) command to set an unconditional or a conditional breakpoint, or the Evaluate (EVAL) command to display a variable's value. You can also use the HELP command to display a list of valid commands with brief descriptions. Figure 3 contains a complete list of the ILE debugger commands, the command abbreviations, and a summarized description.
Now, suppose you want to examine some variables in the program being debugged in 2. First, you establish a breakpoint so the program will stop running before it completes. You could place the cursor on the last (only) C-spec and press the Toggle Breakpoint function key (F6). A message is displayed at the bottom of the screen, Breakpoint added to line 14. Next, exit the program with F3 or F12 and then call it. The program will run until the breakpoint is reached and then the program source will be displayed again. Now, you can examine any of the program's fields.
Now, suppose you want to examine some variables in the program being debugged in Figure 2. First, you establish a breakpoint so the program will stop running before it completes. You could place the cursor on the last (only) C-spec and press the Toggle Breakpoint function key (F6). A message is displayed at the bottom of the screen, Breakpoint added to line 14. Next, exit the program with F3 or F12 and then call it. The program will run until the breakpoint is reached and then the program source will be displayed again. Now, you can examine any of the program's fields.
Say you want to examine the PKDDEC0502 field. You could either position the cursor in the field and press F11 or use the EVAL debug command at the command line.
EVAL PKDDEC0502
The field value is displayed at the bottom of the screen as PKDDEC0502 = 125.30.
If you want to display the hexadecimal value of field PKDFLD0502, you can't use the F11 key. You must use the EVAL command with a slight modification. Key in this command to display the hexadecimal value at the bottom of the screen.
EVAL PKDFLD0502: X
If you want to display the hexadecimal value of the BINARY0902 field, you still cannot use the F11 key. Use the EVAL command syntax just as you did for the PKDFLD0502 field.
EVAL BINARY0902: X
The hexadecimal value of BINARY0902 appears at the bottom of the screen. Now, suppose you want to display the value of the YYMMDD data structure. Position the cursor in the YYMMDD data structure name and use the F11 key or use the EVAL command.
EVAL YYMMDD
This time the Evaluate Expression display appears, as illustrated in 4. Notice that the screen displays all subfield values for data structure YYMMDD. Similarly, if you display an array, the debugger will display all elements of the array. The Evaluate Expression display appears because the value of the data structure YYMMDD can't be displayed at the bottom of the screen on a single line.
This time the Evaluate Expression display appears, as illustrated in Figure 4. Notice that the screen displays all subfield values for data structure YYMMDD. Similarly, if you display an array, the debugger will display all elements of the array. The Evaluate Expression display appears because the value of the data structure YYMMDD can't be displayed at the bottom of the screen on a single line.
You can also display the Evaluate Expression screen by pressing Enter from the Display Module Source screen when the command line is empty. The Evaluate Expression display is useful if you've displayed a number of variables and you need to review what you have seen.
A powerful optional feature of the EVAL command is its ability to change a program variable. For example, to change the value of field CHRSTR06 from MoJoMan to MoJoBoy, key in this command.
EVAL CHRSTR06 = 'MoJoBoy'
You can assign a value to a character variable using a hexadecimal value by qualifying the character literal with an X. For example, say you want to assign the logical not character () to a variable called SYMBOL, but the character doesn't exist on your keyboard. You could assign the hexadecimal representation of the character () with the EVAL command.
EVAL SYMBOL = X'5F'
The ILE debugger is great, but the source-level function isn't available to you automatically. First, you must be sure to create your ILE modules with the correct debug view.
One Preliminary Step
Before you can debug an ILE program at the source level, you must create the modules with the DBGVIEW parameter set to a value that will give you the view you want. The three views available are Root (source), List, and Statement.
The Root view displays the source statements found in the module's source member.
The List view displays the source statements generated on the compile listing. Normally, these include any source member statements, any statements included from externally described files, and any source statements included by the /COPY compiler directive.
The Statement view displays no source statements and is the default debug view for the Create Program (CRTPGM) command and the Create xxx Module (CRTxxxMOD) command (xxx is the language abbreviation). Unless you change the view when you create your ILE modules or programs, you won't be able to perform any source- level debugging. If you want source-level debugging, don't use this view.
A Vast Improvement
One function I would like to see in the ILE source debugger is the ability to watch a variable. This function would allow the constant and dynamic display of selected variables' values as you step through the program. With PC compilers, this watch function usually occurs through a window. Another feature I would like to see added is the ability to evoke a program when the debugger is started.
Although the ILE source debugger doesn't have all the features of some debuggers, it's a vast improvement over what we had. The AS/400 finally has a debugger that can help programmers find program bugs in an efficient manner.
Richard Shaler is a senior technical editor for Midrange Computing.
The ILE Source Debugger
Figure 1 Observability Information and ILE Programs
UNABLE TO REPRODUCE GRAPHICS
The ILE Source Debugger
Figure 2 The Display Module Source Display
UNABLE TO REPRODUCE GRAPHICS
The ILE Source Debugger
Figure 3 The ILE Source Debugger Commands
Command Abr. Description ATTR A Displays the attributes of a variable (type and length). BREAK BR Enters unconditional and conditional breakpoints. CLEAR C Removes unconditional and conditional breakpoints. DISPLAY DI Displays the names and definitions assigned by using the EQUATE command. It also allows you to display a different source module. EQUATE EQ Assigns an expression, variable, or debug command to a name for shorthand use. EVAL EV Displays or changes the value of a variable, or displays the value of expressions, records, structures, or arrays. QUAL Q Defines the scope of variables that appear in subsequent EVAL commands. Does not apply to ILE RPG. STEP S Runs one or more statements of the program being debugged. FIND F Searches forward or backward in the module currently displayed for a specified line number, string, or text. UP U Moves the displayed window of source toward the beginning of the view by the amount entered. DOWN DO Moves the displayed window of source toward the end of the view by the amount entered. LEFT L Moves the displayed window of source to the left by the amount entered. RIGHT R Moves the displayed window of source to the right by the amount entered. TOP T Positions the view to show the first line. BOTTOM BO Positions the view to show the last line. NEXT N Positions the view to the next breakpoint in the source currently displayed. PREVIOUS P Positions the view to the previous breakpoint in the source currently displayed. HELP H Shows the on-line help information for the available source-debugger commands.
The ILE Source Debugger
Figure 4 The Evaluate Expression Display
UNABLE TO REPRODUCE GRAPHICS
LATEST COMMENTS
MC Press Online