[an error occurred while processing this directive]

HP OpenVMS Systems Documentation

Content starts here

HP OpenVMS Debugger Manual


Previous Contents Index

4.1.6.1 Using Variables in Language Expressions

You can use variables in language expressions in much the same way that you use them in the source code of your program.

Thus, the debugger generally interprets a variable used in a language expression as the current value of that variable, not the address of the variable. For example (X is an integer variable):



DBG> DEPOSIT X = 12     ! Assign the value 12 to X.
DBG> EXAMINE X          ! Display the value of X.
MOD4\X:  12
DBG> EVALUATE X         ! Evaluate and display the value of X.
12
DBG> EVALUATE X + 4     ! Add the value of X to 4.
16
DBG> DEPOSIT X = X/2    ! Divide the value of X by 2 and assign
                        ! the resulting value to X.
DBG> EXAMINE X          ! Display the new value of X.
MOD4\X:   6
DBG>

Using a variable in a language expression as shown in the previous examples is generally limited to single-valued, noncomposite variables. Typically, you can specify a multivalued, composite variable (like an array or record) in a language expression only if the syntax indicates that you are referencing only a single value (a single element of the aggregate). For example, if ARR is the name of an array of integers, the following command is invalid:



DBG> EVALUATE ARR
%DEBUG-W-NOVALUE, reference does not have a value
DBG>

However, the following commands are valid because only a single element of the array is referenced:



DBG> EVALUATE ARR(2)         ! Evaluate element 2 of array ARR.
37
DBG> DEPOSIT K = 5 + ARR(2)  ! Deposit the sum of two integer
DBG>                         ! values into an integer variable.

If the current language is BLISS, the debugger interprets a variable in a language expression as the address of that variable. To denote the value stored in a variable, you must use the contents-of operator (period (.)). For example, when the language is set to BLISS:



DBG> EXAMINE Y           ! Display the value of Y.
MOD4\Y:  3
DBG> EVALUATE Y          ! Display the address of Y.
02475B
DBG> EVALUATE .Y         ! Display the value of Y.
3
DBG> EVALUATE Y + 4      ! Add 4 to the address of Y and
02475F                   ! display the resulting value.
DBG> EVALUATE .Y + 4     ! Add 4 to the value of Y and display
7                        ! the resulting value.
DBG>

For all languages, to obtain the address of a variable, use the
EVALUATE/ADDRESS command as described in Section 4.1.11. The EVALUATE and EVALUATE/ADDRESS commands both display the address of an address expression when the language is set to BLISS.

4.1.6.2 Numeric Type Conversion by the Debugger

When evaluating language expressions involving numeric types of different precision, the debugger first converts lower-precision types to higher-precision types before performing the evaluation. In the following example, the debugger converts the integer 1 to the real 1.0 before doing the addition:



DBG> EVALUATE 1.5 + 1
2.5
DBG>

The basic rules are as follows:

  • If integer and real types are mixed, the integer type is converted to the real type.
  • If integer types of different sizes are mixed (for example, byte-integer and word-integer), the one with the smaller size is converted to the larger size.
  • If real types of different sizes are mixed (for example, S_float and T_float), the one with the smaller size is converted to the larger size.

In general, the debugger allows more numeric type conversion than the programming language. In addition, the hardware type used for a debugger calculation (word, longword, S_float, and so on) might differ from that chosen by the compiler. Because the debugger is not as strongly typed or as precise as some languages, the evaluation of an expression by the EVALUATE command might differ from the result that would be calculated by compiler-generated code and obtained with the EXAMINE command.

4.1.7 Address Expressions Compared to Language Expressions

Do not confuse address expressions with language expressions. An address expression specifies a program location; a language expression specifies a value. In particular, the EXAMINE command expects an address expression as its parameter, and the EVALUATE command expects a language expression as its parameter. These points are shown in the next examples.

In the following example, the value 12 is deposited into the variable X. This is confirmed by the EXAMINE command. The EVALUATE command computes and displays the sum of the current value of X and the integer literal 6,



DBG> DEPOSIT X = 12
DBG> EXAMINE X
MOD3\X: 12
DBG> EVALUATE X + 6
18
DBG>

In the next example, the EXAMINE command displays the value currently stored at the memory location that is 6 bytes beyond the address of X:



DBG> EXAMINE X + 6
MOD3\X+6: 274903
DBG>

In this case the location is not associated with a compiler-generated type. Therefore, the debugger interprets and displays the value stored at that location in the type longword integer (see Section 4.1.5).

In the next example, the value of X + 6 (that is, 18) is deposited into the location that is 6 bytes beyond the address of X. This is confirmed by the last EXAMINE command.



DBG> EXAMINE X
MOD3\X: 12
DBG> DEPOSIT X + 6 = X + 6
DBG> EXAMINE X
MOD3\X: 12
DBG> EXAMINE X + 6
MOD3\X+6: 18
DBG>

4.1.8 Specifying the Current, Previous, and Next Entity

When using the EXAMINE and DEPOSIT commands, you can use three special built-in symbols (address expressions) to refer quickly to the current, previous, and next data locations (logical entities). These are the period (.), the circumflex (^), and the Return key.

The period (.), when used by itself with an EXAMINE or DEPOSIT command, denotes the current entity---that is, the program location most recently referenced by an EXAMINE or DEPOSIT command. For example:



DBG> EXAMINE X
SIZE\X: 7
DBG> DEPOSIT . = 12
DBG> EXAMINE .
SIZE\X: 12
DBG>

The circumflex (^) and Return key denote, respectively, the previous and next logical data locations relative to the last EXAMINE or DEPOSIT command (the logical predecessor and successor, respectively). The circumflex and Return key are useful for referring to consecutive indexed components of an array. The following example shows the use of these operators with an array of integers, ARR:



DBG> EXAMINE ARR(5)    ! Examine element 5 of array ARR.
MAIN\ARR(5): 448670
DBG> EXAMINE ^         ! Examine the previous element (4).
MAIN\ARR(4): 792802
DBG> EXAMINE [Return]          ! Examine the next element (5).
MAIN\ARR(5): 448670
DBG> EXAMINE [Return]          ! Examine the next element (6).
MAIN\ARR(6): 891236
DBG>

The debugger uses the type associated with the current entity to determine logical successors and predecessors.

You can also use the built-in symbols %CURLOC, %PREVLOC, and %NEXTLOC to achieve the same purpose as the period, circumflex, and Return key, respectively. These symbols are useful in command procedures and also if your program uses the circumflex for other purposes. Moreover, using the Return key to signify the logical successor does not apply to all contexts. For example, you cannot press the Return key after entering the DEPOSIT command to indicate the next location, but you can always use the symbol %NEXTLOC for that purpose.

Note that, like EXAMINE and DEPOSIT, the EVALUATE/ADDRESS command also resets the values of the current, previous, and next logical-entity built-in symbols (see Section 4.1.11). However, you cannot press the Return key after entering the EVALUATE/ADDRESS command to indicate the next location. For more information about debugger built-in symbols, see Appendix B.

The previous examples show the use of the built-in symbols after referencing a symbolic name with the EXAMINE or DEPOSIT command. If you examine or deposit into a memory address, that location might or might not be associated with a compiler-generated type. When you reference a memory address, the debugger uses the following conventions to determine logical predecessors and successors:

  • If the address has a symbolic name (the name of a variable, component of a composite variable, routine, and so on), the debugger uses the associated compiler-generated type.
  • If the address does not have a symbolic name, the debugger uses the type longword integer by default.

As the current entity is reset with new examine or deposit operations, the debugger associates each new location with a type in the manner indicated to determine logical successors and predecessors. This is shown in the following examples.

Assume that a Fortran program has declared three variables, ARY, FLT, and BTE, as follows:

  • ARY is an array of three word integers (2 bytes each)
  • FLT is an F_floating type (4 bytes)
  • BTE is a byte integer (1 byte)

Assume that storage for these variables has been allocated at consecutive addresses in memory, starting with 1000. For example:


1000: ARY(1)
1002: ARY(2)
1004: ARY(3)
1006: FLT
1010: BTE
1011: undefined
   .
   .
   .

Examining successive logical data locations will give the following results:



DBG> EXAMINE 1000        ! Examine ARY(1), associated with 1000.
MOD3\ARY(1):  13         ! Current entity is now ARY(1).
DBG> EXAMINE        ! Examine next location, ARY(2),
MOD3\ARY(2):   7         ! using type of ARY(1) as reference.
DBG> EXAMINE        ! Examine next location, ARY(3).
MOD3\ARY(3):  19         ! Current entity is now ARY(3).
DBG> EXAMINE        ! Examine entity at 1006 (FLT).
MOD3\FLT:  1.9117807E+07 ! Current entity is now FLT.
DBG> EXAMINE        ! Examine entity at 1010 (BTE).
MOD3\BTE:   43           ! Current entity is now BTE.
DBG> EXAMINE        ! Examine entity at 1011 (undefined).
1011: 17694732           ! Interpret data as longword integer.
DBG>                     ! Location is not symbolized.

The same principles apply when you use type qualifiers with the EXAMINE and DEPOSIT commands (see Section 4.5.2). The type specified by the qualifier determines the data boundary of an entity and, therefore, any logical successors and predecessors.

4.1.9 Language Dependencies and the Current Language

The debugger enables you to set your debugging context to any of several supported languages. The setting of the current language determines how the debugger parses and interprets the names, numbers, operators, and expressions you specify in debugger commands, and how it displays data.

By default, the current language is the language of the module containing the main program, and it is identified when you bring the program under debugger control. For example:



$ PASCAL/NOOPTIMIZE/DEBUG TEST1
$ LINK/DEBUG TEST1
$ DEBUG/KEEP
           Debugger Banner and Version Number
DBG> RUN TEST1
Language: PASCAL, Module: TEST1
DBG>

When debugging modules whose code is written in other languages, you can use the SET LANGUAGE command to establish a new language-dependent context. Section 14.3 highlights some important language differences. Debugger support for operators and other constructs in language expressions is listed for each language in the debugger's online help (type HELP Language).

4.1.10 Specifying a Radix for Entering or Displaying Integer Data

The debugger can interpret and display integer data in any one of four radixes: decimal, hexadecimal, octal, and binary. The default radix is decimal for most languages.

On VAX processors, the exceptions are BLISS and MACRO--32, which have a default radix of hexadecimal.

On Alpha processors, the exceptions are BLISS, MACRO--32 and MACRO--64, which have a default radix of hexadecimal.

You can control the radix for the following kinds of integer data:

  • Data that you specify in address expressions or language expressions
  • Data that is displayed by the EVALUATE and EXAMINE commands

You cannot control the radix for other kinds of integer data. For example, addresses are always displayed in hexadecimal radix in a SHOW CALLS display. Or, when specifying an integer n with various command qualifiers (/AFTER:n, /UP:n, and so on), you must use decimal radix.

The technique you use to control radix depends on your objective. To establish a new radix for all subsequent commands, use the SET RADIX command. For example:



DBG> SET RADIX HEXADECIMAL

After this command is executed, all integer data that you enter in address or language expressions is interpreted as being hexadecimal. Also, all integer data displayed by the EVALUATE and EXAMINE commands is given in hexadecimal radix.

The SHOW RADIX command identifies the current radix (which is either the default radix, or the radix last established by a SET RADIX command). For example:



DBG> SHOW RADIX
input radix: hexadecimal
output radix: hexadecimal
DBG>

The SHOW RADIX command identifies both the input radix (for data entry) and the output radix (for data display). The SET RADIX command qualifiers /INPUT and /OUTPUT enable you to specify different radixes for data entry and display. For more information, see the SET RADIX command.

Use the CANCEL RADIX command to restore the default radix.

The examples that follow show several techniques for displaying or entering integer data in another radix without changing the current radix.

To convert some integer data to another radix without changing the current radix, use the EVALUATE command with a radix qualifier (/BINARY, /DECIMAL, /HEXADECIMAL, /OCTAL). For example:



DBG> SHOW RADIX
input radix: decimal
output radix: decimal
DBG> EVALUATE 18 + 5
23                         ! 23 is decimal integer.
DBG> EVALUATE/HEX 18 + 5
00000017                   ! 17 is hexadecimal integer.
DBG>

The radix qualifiers do not affect the radix for data entry.

To display the current value of an integer variable (or the contents of a program location that has an integer type) in another radix, use the EXAMINE command with a radix qualifier. For example:



DBG> EXAMINE X
MOD4\X: 4398                ! 4398 is a decimal integer.
DBG> EXAMINE/OCTAL .        ! X is the current entity.
MOD4\X: 00000010456         ! 10456 is an octal integer.
DBG>

To enter one or more integer literals in another radix without changing the current radix, use one of the radix built-in symbols %BIN, %DEC, %HEX, or %OCT. A radix built-in symbol directs the debugger to treat an integer literal that follows (or all numeric literals in a parenthesized expression that follows) as a binary, decimal, hexadecimal, or octal number, respectively. These symbols do not affect the radix for data display. For example:


DBG> SHOW RADIX
input radix: decimal
output radix: decimal
DBG> EVAL %BIN 10             ! Evaluate the binary integer 10.
2                             ! 2 is a decimal integer.
DBG> EVAL %HEX (10 + 10)      ! Evaluate the hexadecimal integer 20.
32                            ! 32 is a decimal integer.
DBG> EVAL %HEX 20 + 33        ! Treat 20 as hexadecimal, 33 as decimal.
65                            ! 65 is a decimal integer.
DBG> EVAL/HEX %OCT 4672       ! Treat 4672 as octal and display in hex.
000009BA                      ! 9BA is a hexadecimal number.
DBG> EXAMINE X + %DEC 12      ! Examine the location 12 decimal bytes
MOD3\X+12:  493847            ! beyond the address of X.
DBG> DEPOS J = %OCT 7777777   ! Deposit an octal value.
DBG> EXAMINE .                ! Display that value in decimal radix.
MOD3\J:  2097151
DBG> EXAMINE/OCTAL .          ! Display that value in octal radix.
MOD3\J:  00007777777
DBG> EXAMINE %HEX 0A34D       ! Examine location A34D, hexadecimal.
SHARE$LIBRTL+4941:  344938193 ! 344938193 is a decimal integer.
DBG>

Note

When specifying a hexadecimal integer that starts with a letter rather than a number (for example, A34D in the last example), add a leading 0. Otherwise, the debugger tries to interpret the integer as a symbol declared in your program.

For more examples showing the use of the radix built-in symbols, see Appendix B.

4.1.11 Obtaining and Symbolizing Memory Addresses

Use the EVALUATE/ADDRESS command to determine the memory address or the register name associated with a symbolic address expression, such as a variable name, line number, routine name, or label. For example:



DBG> EVALUATE/ADDRESS X       ! A variable name
2476
DBG> EVALUATE/ADDRESS SWAP    ! A routine name
1536
DBG> EVALUATE/ADDRESS %LINE 26
1629
DBG>

The address is displayed in the current radix (as defined in Section 4.1.10). You can specify a radix qualifier to display the address in another radix. For example:



DBG> EVALUATE/ADDRESS/HEX X
000009AC
DBG>

If a variable is associated with a register instead of a memory address, the EVALUATE/ADDRESS command displays the name of the register, regardless of whether a radix qualifier is used. The following command indicates that variable K (a nonstatic variable) is associated with register R2:



DBG> EVALUATE/ADDRESS K
%R2
DBG>

Like the EXAMINE and DEPOSIT commands, EVALUATE/ADDRESS resets the values of the current, previous, and next logical-entity built-in symbols (see Section 4.1.8). Unlike the EVALUATE command, EVALUATE/ADDRESS does not affect the current-value built-in symbols %CURVAL and backslash (\).

The SYMBOLIZE command does the reverse of EVALUATE/ADDRESS, but without affecting the current, previous, or next logical-entity built-in symbols. It converts a memory address or a register name into its symbolic representation (including its path name) if such a representation is possible (Chapter 5 explains how to control symbolization). For example, the following command shows that variable K is associated with register R2:



DBG> SYMBOLIZE %R2
address MOD3\%R2:
    MOD3\K
DBG>

By default, symbolic mode is in effect (SET MODE SYMBOLIC). Therefore, the debugger displays all addresses symbolically if symbols are available for the addresses. For example, if you specify a numeric address with the EXAMINE command, the address is displayed in symbolic form if symbolic information is available:



DBG> EVALUATE/ADDRESS X
2476
DBG> EXAMINE 2476
MOD3\X:  16
DBG>

However, if you specify a register that is associated with a variable, the EXAMINE command does not convert the register name to the variable name. For example:



DBG> EVALUATE/ADDRESS K
%R2
DBG> EXAMINE %R2
MOD3\%R2:  78
DBG>

By entering the SET MODE NOSYMBOLIC command, you disable symbolic mode and cause the debugger to display numeric addresses rather than their symbolic names. When symbolization is disabled, the debugger might process commands somewhat faster because it does not need to convert numbers to names. The EXAMINE command has a /[NO]SYMBOLIC qualifier that enables you to control symbolization for a single EXAMINE command. For example:



DBG> EVALUATE/ADDRESS Y
512
DBG> EXAMINE 512
MOD3\Y:  28
DBG> EXAMINE/NOSYMBOLIC 512
512:  28
DBG>

Symbolic mode also affects the display of instructions.

For example, on VAX processors:



DBG> EXAMINE/INSTRUCTION .%PC
MOD5\%LINE 14+2: MOVAL   L^MOD4\X,R11
DBG> EXAMINE/NOSYMBOL/INSTRUCTION .%PC
1538:   MOVAL   L^1080,R11
DBG>



4.2 Examining and Depositing into Variables

The examples in this section show how to use the EXAMINE and DEPOSIT commands with variables.

Languages differ in the types of variables they use, the names for these types, and the degree to which different types can be intermixed in expressions. The following generic types are discussed in this section:

  • Scalars (such as integer, real, character, or Boolean)
  • Strings
  • Arrays
  • Records
  • Pointers (access types)

The most important consideration when examining and manipulating variables in high-level language programs is that the debugger recognizes the names, syntax, type constraints, and scoping rules of the variables in your program. Therefore, when specifying a variable with the EXAMINE or DEPOSIT command, you use the same syntax that is used in the source code. The debugger processes and displays the data accordingly. Similarly, when assigning a value to a variable, the debugger follows the typing rules of the language. It issues a diagnostic message if you try to deposit an incompatible value. The examples in this section show some of these invalid operations and the resulting diagnostics.

When using the DEPOSIT command (or any other command), note the following behavior. If the debugger issues a diagnostic message with a severity level of I (informational), the command is still executed (the deposit is made in this case). The debugger aborts an illegal command line only when the severity level of the message is W (warning) or greater.

For additional language-specific information, see the debugger's online help (type HELP Language).


Previous Next Contents Index