HP OpenVMS Systems Documentation
HP BASIC for OpenVMS
After you link your program, use the DCL command RUN to execute it. The RUN command has the following format:
RUN [/[NO]DEBUG] file-spec [/[NO]DEBUG]
/[NO]DEBUGThe /[NO]DEBUG qualifier is optional. Specify the /DEBUG qualifier to request the debugger if the image is not linked with it. You cannot use /DEBUG on images linked with the /NOTRACEBACK qualifier. If the image is linked with the /DEBUG qualifier, and you do not want the debugger to prompt, use the /NODEBUG qualifier. The default action depends on whether the file is linked with the /DEBUG qualifier.
file-specThe name of the file you want to execute.
The following example executes the image SAMPLE.EXE without invoking the debugger:
$ RUN SAMPLE/NODEBUG
See Chapter 3 for more information about debugging programs.
During program execution, an image can generate a fatal error called an
exception condition. When an exception condition
occurs, HP BASIC displays an error message. Run-time errors can
also be issued by other facilities, such as the OpenVMS operating
system. For more information about run-time errors, see Appendix B.
2.3.1 Improving Run-Time Performance of HP BASIC Programs
Even with fast hardware and an optimizing compiler, you can still tune your code for run-time performance. This section provides recommendations to consider if further performance improvements are desirable.
To achieve the best performance for your application, it is important
to let both the hardware and the optimizer/code generator take
advantage of their full capabilities. This can be accomplished by
minimizing, and in some cases avoiding, the use of language features
and qualifiers that block optimal program execution.
18.104.22.168 Data Items
Choose data types and align data items with the following in mind:
On your BASIC command line, consider the following when you specify qualifiers:
The statements used in a program can affect performance, as follows:
Dynamic string variables
Executable DIM statements
EXTERNAL string functions
MOVE statements for an entire array
ON ERROR statements
Built-in string functions
This chapter discusses OpenVMS Debugger information that is specific to
the BASIC language. For more information about the OpenVMS Debugger,
see the HP OpenVMS Debugger Manual. Online help is available during debugging
3.1 Overview of the Debugger
A debugger is a tool to help you locate run-time errors quickly. It is used with a program that has already been compiled and linked successfully, with no errors reported, but that does not run correctly. For example, the output might be obviously wrong, the program goes into an infinite loop, or the program terminates prematurely. The debugger enables you to observe and manipulate the program's execution interactively, step by step, until you locate the point at which the program stopped working correctly.
The OpenVMS Debugger is a symbolic debugger, which means that you can refer to program locations by the symbols (names) you used for those locations in your program---the names of variables, routines, labels, and so on. You do not have to use virtual addresses to refer to memory locations.
The debugger recognizes the syntax, expressions, data typing, and other
constructs of BASIC.
3.2 Compiling and Linking to Prepare for Debugging
$ BASIC/DEBUG INVENTORY $ LINK/DEBUG INVENTORY
The /DEBUG qualifier with the BASIC command instructs the compiler to write the debug symbol records associated with INVENTORY into the object module, INVENTORY.OBJ. These records allow you to use the names of variables and other symbols declared in INVENTORY in debugger commands. (If your program has several compilation units, you must compile each unit that you want to debug with the /DEBUG qualifier.)
The /DEBUG qualifier with the LINK command instructs the linker to
include all symbol information that is contained in INVENTORY.OBJ in
the executable image. The qualifier also causes the OpenVMS image
activator to start the debugger at run time. (If your program has
several object modules, you might need to specify other modules in the
3.3 Viewing Your Source Code
The debugger provides two methods for viewing source code: noscreen
mode and screen mode. By default when you invoke the debugger, you are
in noscreen mode, but you might find that it is easier to view your
source code with screen mode. Both modes are described in the following
3.3.1 Noscreen Mode
Noscreen mode is the default, line-oriented mode of displaying input and output. To get into noscreen mode from screen mode, enter SET MODE NOSCREEN. See the sample debugging session in Section 3.7 for a demonstration of noscreen mode.
DBG> TYPE 3 3: EXTERNAL SUB TRIPLE & DBG>
The display of source lines is independent of program execution. You can use the TYPE command to display source code from a module other than the one currently executing. In that case, you need to use a directory specification to specify the module. For example, the following command displays lines 16 to 21 of module TEST:
DBG> TYPE TEST\16:21
To invoke screen mode, press PF3. In screen mode, by default the debugger splits the screen into three displays called SRC, OUT, and PROMPT.
--SRC: module SAMPLE$MAIN -scroll-source-------------------------- 1: 10 !SAMPLE 2: 3: EXTERNAL SUB TRIPLE & 4: ,PRINT_SUB 5: 6: WHEN ERROR USE HANDLER_1 -> 7: CALL TRIPLE 8: CALL PRINT_SUB 9: - OUT -output--------------------------------------------- stepped to SAMPLE$MAIN\%LINE 7 - PROMPT -error-program-prompt---------------------------- DBG> STEP DBG>
The SRC display, at the top of the screen, shows the source code of the module (compilation unit) that is currently executing. An arrow in the left column points to the next line to be executed, which corresponds to the current location of the program counter (PC). The line numbers, which are assigned by the compiler, match those in a listing file.
BASIC line numbers are treated as text by the debugger. In this chapter, line numbers refer to the sequential line numbers generated by the compiler. When a program includes or appends code from another file, the included lines of code are also numbered in sequence by the compiler. These line numbers are on the extreme left of a listing file. An explanation of the listing file format is in Chapter 2.
The PROMPT display, at the bottom of the screen, shows the debugger prompt (DBG>), your input, debugger diagnostic messages, and program output. In the example, the debugger commands that have been issued are shown.
The OUT display, in the center of the screen, captures the debugger's output in response to the commands that you issue.
The SRC and OUT displays are scrollable so that you can see whatever information scrolls beyond the display window's edge. Press KP8 to scroll up and KP2 to scroll down. Press KP3 to change the display to be scrolled (by default, the SRC display is scrolled). Scrolling a display does not affect program execution.
If the debugger cannot locate source lines for the currently executing module, it tries to display source lines in the next module down on the call stack for which source lines are available and issues the following message:
%DEBUG-I-SOURCESCOPE, Source lines not available for .0\%PC. Displaying source in a caller of the current routine.
Source lines might not be available for the following reasons:
This section discusses the following:
There are two commands for starting or resuming program execution: GO and STEP. The GO command starts execution. The STEP command lets you execute a specified number of source lines or instructions.
The GO command starts program execution, which continues until forced to stop. You will probably use the GO command most often in conjunction with breakpoints, tracepoints, and watchpoints. If you set a breakpoint in the path of execution and then enter the GO command (or press the keypad comma key that executes the GO command), execution will be suspended when the program reaches that breakpoint. If you set a tracepoint, the path of execution through that tracepoint will be monitored. If you set a watchpoint, execution will be suspended when the value of the watched variable changes.
You can also use the GO command to test for an exception condition or an infinite loop. If an exception condition that is not handled by your program occurs, the debugger will take over and display the DBG> prompt so that you can issue commands. If you are using screen mode, the pointer in the source display will indicate where execution stopped. You can then use the SHOW CALLS command (see Section 3.4.2) to identify the currently active routine calls (the call stack).
In the case of an infinite loop, the program will not terminate, so the debugger prompt will not reappear. To obtain the prompt, interrupt the program by pressing Ctrl/Y and then issue the DCL command DEBUG. You can then look at the source display and a SHOW CALLS display to locate the PC.
The STEP command (which you can use either by entering STEP or by pressing KP0) allows you to execute a specified number of source lines or instructions, or to execute the program to the next instruction of a particular kind, for example, to the next CALL instruction.
By default, the STEP command executes a single source line at a time. In the following example, the STEP command executes one line, reports the action ("stepped to..."), and displays the line number (27) and source code of the next line to be executed:
DBG> STEP stepped to TEST\COUNTER\%LINE 27 27: X = X + 1 DBG>
The PC is now at the first machine code instruction for line 27 of the module TEST; line 27 is in COUNTER, a routine within the module TEST. TEST\COUNTER\%LINE 27 is a directory specification. The debugger uses directory specifications to refer to symbols. (However, you do not need to use a path name in referring to a symbol, unless the symbol is not unique; in that case, the debugger will issue an error message.) See the HP OpenVMS Debugger Manual or online help for more information about resolving multiply-defined symbols.
You can specify a number of lines for the STEP command to execute. In the following example, the STEP command executes three lines:
DBG> STEP 3
Note that only those source lines for which code instructions were generated by the compiler are recognized as executable lines by the debugger. The debugger skips over any other lines---for example, comment lines.
Also, if a line has more than one statement on it, the debugger will execute all the statements on that line as part of the single step.
Using the STEP/OVER command to step over a GOSUB statement will still proceed to the target of the GOSUB since this statement is just a special kind of GOTO statement and not a routine call.
You can specify different stepping modes, such as stepping by
instruction rather than by line (SET STEP INSTRUCTION). To resume to
the default behavior, enter the SET STEP LINE command. Also by default,
the debugger steps over called routines---execution is not suspended
within a called routine, although the routine is executed. By entering
the SET STEP INTO command, you tell the debugger to suspend execution
within called routines as well as within the currently executing
module. To resume the default behavior, enter the SET STEP OVER command.
3.4.2 Determining the Current Location of the Program Counter
The SHOW CALLS command lets you determine the current location of the program counter (PC) (for example, after returning to the debugger following a Ctrl/Y interrupt). The command shows a traceback that lists the sequence of calls leading to the currently executing routine. For example:
DBG> SHOW CALLS module name routine name line rel PC abs PC *TEST PRODUCT 18 00000009 0000063C *TEST COUNTER 47 00000009 00000647 *MY_PROG MY_PROG 21 0000000D 00000653 DBG>
For each routine (beginning with the currently executing routine), the debugger displays the following information:
This example indicates that execution is currently at line 18 of
routine PRODUCT (in module TEST), which was called from line 47 of
routine COUNTER (in module TEST), which was called from line 21 of
routine MY_PROG (in module MY_PROG).
3.4.3 Suspending Program Execution
The SET BREAK command lets you select breakpoints, which are locations at which the program will stop running. When you reach a breakpoint, you can enter commands to check the call stack, examine the current values of variables, and so on.
A typical use of the SET BREAK command is shown in the following example:
DBG> SET BREAK COUNTER DBG> GO . . . break at TEST\COUNTER 34: SUB COUNTER(LONG X,Y) DBG>
In this example, the SET BREAK command sets a breakpoint on the subprogram COUNTER; the GO command starts execution. When the subprogram COUNTER is encountered, execution is suspended, the debugger announces that the breakpoint at COUNTER has been reached (break at ...), displays the source line (34) where execution is suspended, and prompts you for another command. At this breakpoint, you can step through the subprogram COUNTER, using the STEP command, and use the EXAMINE command (see Section 3.5.1) to check on the current values of X and Y.
When using the SET BREAK command, you can specify program locations using various kinds of address expressions (for example, line numbers, routine names, instructions, virtual memory addresses). With high-level languages, you typically use routine names, labels, or line numbers, possibly with directory specifications to ensure uniqueness.
Routine names and labels should be specified as they appear in the source code. Line numbers may be derived from either a source code display or a listing file. When specifying a line number, use the prefix %LINE. (Otherwise, the debugger will interpret the line number as a memory location.) For example, the next command sets a breakpoint at line 41 of the currently executing module; the debugger will suspend execution when the PC is at the start of line 41:
DBG> SET BREAK %LINE 41
Note that you can set breakpoints only on lines that resulted in machine code instructions. The debugger warns you if you try to do otherwise (for example, on a comment line). If you want to pick a line number in a module other than the one currently executing, you need to specify the module's name in a directory specification. For example:
DBG> SET BREAK SCREEN_IO\%LINE 58
You do not always have to specify a particular program location, such as line 58 or COUNTER, to set a breakpoint. You can set breakpoints on events, such as exceptions. You can use the SET BREAK command with a qualifier, but no parameter, to break on every line, or on every CALL instruction, and so on. For example:
DBG> SET BREAK/LINE DBG> SET BREAK/CALL
You can conditionalize a breakpoint (with a WHEN clause) or specify that a list of commands be executed at the breakpoint (with a DO clause on the debugger command). For example, the next command sets a breakpoint on the label LOOP3. The DO (EXAMINE TEMP) clause causes the value of the variable TEMP to be displayed whenever the breakpoint is triggered.
DBG> SET BREAK LOOP3 DO (EXAMINE TEMP) DBG> GO . . . break at COUNTER\LOOP3 37: LOOP3: FOR I = 1 TO 10 COUNTER\TEMP: 284.19 DBG>
To display the currently active breakpoints, enter the SHOW BREAK command:
DBG> SHOW BREAK breakpoint at SCREEN_IO\%LINE 58 breakpoint at COUNTER\LOOP3 do (EXAMINE TEMP) . . . DBG>