[an error occurred while processing this directive]

HP OpenVMS Systems Documentation

Content starts here

OpenVMS Debugger Manual


Previous Contents Index

C.3.10.2 Monitoring Specific Exceptions

Whenever an exception is raised, the debugger sets the following built-in symbols. You can use them to qualify exception breakpoints or tracepoints so that they trigger only on certain exceptions.

%EXC_FACILITY A string that names the facility that issued the exception. The facility name for Ada predefined exceptions and user-defined exceptions is ADA.
%EXC_NAME An uppercase string that names the exception. If the exception raised is an Ada predefined exception, its name is truncated if it exceeds 15 characters. For example, CONSTRAINT_ERROR is truncated to CONSTRAINT_ERRO. If the exception is a user-defined exception, %EXC_NAME contains the string "EXCEPTION", and the name of the user-defined exception is contained in %ADAEXC_NAME.
%ADAEXC_NAME If the exception raised is user-defined, %ADAEXC_NAME contains a string that names the exception, and %EXC_NAME contains the string "EXCEPTION". If the exception is not user-defined, %ADAEXC_NAME contains a null string, and the name of the exception is contained in %EXC_NAME.
%EXC_NUM The number of the exception.
%EXC_SEVERITY A string that gives the exception severity level (F, E, W, I, S, or ?).

C.3.10.3 Monitoring Handled Exceptions and Exception Handlers

The SET BREAK/EVENT and SET TRACE/EVENT commands let you set breakpoints and tracepoints on exceptions that are about to be handled by Ada exception handlers. These commands let you observe the execution of each Ada exception handler that gains control.

You can specify two event names with these commands:

HANDLED Triggers when an exception is about to be handled in an Ada exception handler (includes HANDLED_OTHERS events).
HANDLED_OTHERS Triggers only when an exception is about to be handled in an Ada exception handler choice others .

For example, the following command sets a breakpoint that triggers whenever an exception is about to be handled by an Ada exception handler:


DBG> SET BREAK/EVENT=HANDLED

When the breakpoint triggers, the debugger identifies the exception that is about to be handled and the exception handler that is about to be executed. You can then use that information to set a breakpoint on a particular handler, or you can enter the GO command, and see which Ada handler next attempts to handle the exception. For example:


DBG> GO
     ...
break on Ada event HANDLED 
  task %TASK 1 is about to handle an exception 
  The Ada exception handler is at: PROCESSOR.%LINE 21 
    %ADA-F-CONSTRAINT_ERRO, CONSTRAINT_ERROR 
    -ADA-I-EXCRAIPRI, Exception raised prior to PC = 00000A7C
DBG> SET BREAK PROCESSOR.%LINE 21; GO

C.3.11 Examining and Manipulating Data

When examining and manipulating data, note the following considerations:

  • Before you can examine or deposit into a nonstatic variable (any variable not declared in a library package), its defining subprogram, task, and so on, must be active on the call stack.
  • Before you can examine, deposit, or evaluate an Ada subprogram formal parameter or an Ada variable, the parameter or variable must be elaborated. In other words, you should step or otherwise move execution past the parameter or variable's declaration. The value contained in any variable or formal parameter whose declaration has not been elaborated might be invalid.

In most cases, the debugger enables you to specify variables and expressions in debugger commands exactly as you would specify them in the source code of the program, including use of qualified expressions. The following subtopics discuss some additional points about debugger support for records and access types.

C.3.11.1 Records

Note the following points about debugger support for records:

  • With certain Ada record variables, the debugger fails to show the record components correctly (possibly with a NOACCESSR error message) when the type declaration is in a different scope than the record (symbol) declaration.
  • With variant records, the debugger lets you examine or assign a value to a component of a variant part that is not active. But because this is an illegal action in Ada, the debugger also issues an informational message. For example, assume that record REC1 has a variant field named STATUS and that the value of STATUS is such that REC1.COMP3 is inactive:


    DBG> EXAMINE REC1.COMP3
    %DEBUG-I-BADDISCVAL, incorrect value of 1 in discriminant 
        field STATUS 
    MAIN.REC1.COMP3:    438
    

C.3.11.2 Access Types

Note the following points about debugger support for access types:

  • The debugger does not support allocators, so you cannot create new access objects with the debugger.
  • When you specify the name of an access object with the EXAMINE command, the debugger displays the memory location of the object it designates.
  • To examine the value of a designated object, you must use selected component notation, specifying .ALL. For example, to examine the value of a record access object designated by A:


    DBG> EXAMINE A.ALL
    EXAMPLE.A.ALL 
        NAME(1..10):        "John Doe  " 
        AGE :       6 
        NEXT:       1462808
    
  • To examine one component of a designated object, you can omit .ALL from the selected component syntax. For example:


    DBG> EXAMINE A.NAME
    EXAMPLE.A.ALL.NAME(1..10):     "John Doe  "
    

The following example shows the debugger support for incomplete types. Consider the following declarations:


package P is
   type T is private; 
private
   type T_TYPE; 
   type T is access T_TYPE; 
end P; 
 
package body P is
   type T_TYPE is
      record
        A: NATURAL := 5; 
        B: NATURAL := 4; 
      end record; 
 
   T_REC: T_TYPE; 
   T_PTR: T := new T_TYPE'(T_REC); 
end P; 
 
with P; use P; 
procedure INCOMPLETE is
   VAR: T; 
begin
   ...
end INCOMPLETE; 

The debugger does not have complete information about the type T, so you cannot manipulate the variable VAR. However, the debugger does have information about objects declared in the package body P. Thus, you can manipulate the variables T_PTR and T_REC.

C.3.12 Module Names and Path Names

The names of Ada debugger modules are the same as the names of the corresponding compilation units, with the following provision. To eliminate ambiguity, an underscore character (_) is appended to a specification name to distinguish it from its body name. For example, TEST (body), TEST_ (specification). To determine the exact names of the modules in your program, use the SHOW MODULE command.

In most cases when you specify a path name, the debugger can distinguish body names and specification names from the context. Therefore, use this naming convention only if needed to resolve an ambiguity.

When the debugger language is set to Ada, the debugger generally constructs pathnames that follow the Ada rules, using selected component notation to separate path name elements (with other languages, a backslash is used to separate elements). For example:


TEST_.A1        ! A1 is declared in the package 
                 ! specification of unit TEST 
TEST.B1         ! B1 is declared in the package 
                 ! body of unit TEST 

The maximum length that you can specify for a subunit path name (expanded name) is 247 characters.

When a use clause makes a symbol declared in a package directly visible outside the package, you do not need to specify an expanded name (package-name.symbol) to refer to the symbol, either in the program itself or in debugger commands.

The SHOW SYMBOL/USE_CLAUSE command identifies any package (library or otherwise) that a specified block, subprogram, or package mentions in a use clause. If the entity specified is a package (library or otherwise), the command also identifies any block, subprogram, package, and so on, that names the specified module in a use clause. For example:


DBG> SHOW SYMBOL/USE_CLAUSE B_
package spec B_ 
    used by:  F 
    uses:     A_

If a label has been assigned to a loop statement or declare block in the source code, the debugger displays the label; otherwise, the debugger displays LOOP$n for a loop statement or BLOCK$n for a declare block, where n is the line number at which the statement or block begins.

C.3.13 Symbol Lookup Conventions

For Ada programs, when you do not specify a path name (including an Ada expanded name), the debugger searches the run-time symbol table as follows.

  1. The debugger looks for the symbol within the block or routine surrounding the current PC value (where execution is currently paused).
  2. If the symbol is not found, the debugger then searches any package that is mentioned in a use clause. The debugger does not distinguish between a library package and a package whose declaration is in the same module as the current scope region. If the same symbol is declared in two or more packages that are visible, the symbol is not unique (according to Ada rules), and the debugger issues a message similar to the following:


    %DEBUG-E-NOUNIQUE, symbol 'X' is not unique
    
  3. If the symbol is still not found, the debugger searches the call stack and other scopes, as for other languages.

C.3.14 Setting Modules

When you or the debugger sets an Ada module, by default the debugger also sets any "related" module (that is, any module whose symbols should be visible within the module being set). Such modules are related to the one being set through either a with-clause or a subunit relationship.

Related module setting takes place as follows. If M1 is the module that is being set, then the following modules are considered related and are also set:

  • If M1 is a library body, the debugger also sets the associated library specification, if any.
  • If M1 is a subunit, the debugger also sets its parent unit and, therefore, any parent of the parent.
  • If M1 mentions a library package P1 in a with clause, the debugger also sets P1's specification. Neither the body of P1 nor any possible subunits of P1 are set, because symbols declared within them should not be visible outside.
    If P1's specification mentions a package P2 in a with clause, the debugger also sets P2's specification. Likewise, if P2's specification mentions a package P3 in a with clause, the debugger also sets P3's specification, and so on. The specifications of all such library packages are set so that you can access data components (for example, record components) that may have been declared in other packages.
  • If M1 mentions a library subprogram in a with clause, the debugger does not set the subprogram. Only the subprogram name needs to be visible in M1 (no declaration within a library subprogram should be visible outside the subprogram). Therefore, the debugger inserts the name of the library subprogram into the RST when M1 is set.

If debugger performance becomes a problem as more modules are set, use the SET MODE NODYNAMIC command, which disables related module setting as well as dynamic module setting. You must then set individual modules explicitly with the SET MODULE command.

By default, the SET MODULE command sets related modules simultaneously with the module specified in the command.

The SET MODULE/NORELATED command sets only the modules you specify explicitly. However, if you use SET MODULE/NORELATED, you may find that a symbol that is declared in another unit and that should be visible at the point of execution is no longer visible or that a symbol which should be hidden by a redeclaration of that same symbol is now visible.

The CANCEL MODULE/NORELATED command deletes from the RST only the modules you specify explicitly. This command, which is the default, deletes related modules in a manner consistent with the intent of Ada's scope and visibility rules. The exact effect depends on module relationships.

The distinction between related and directly related for subunits is analogous to that for library packages.

C.3.14.1 Setting Modules for Package Bodies

Modules for package bodies are not automatically set by the debugger.

You may need to set the modules for library package bodies yourself so that you can debug the package body or debug subprograms declared in the corresponding package specification.

C.3.15 Resolving Overloaded Names and Symbols

When you encounter overloaded names and symbols, the debugger issues a message like the following:


%DEBUG-E-NOTUNQOVR, symbol 'ADD' is overloaded 
     use SHOW SYMBOL to find the unique symbol names

If the overloaded symbol is an enumeration literal, you can use qualified expressions to resolve the overloadings.

If the overloaded symbol represents a subprogram or task accept statement, you can use the unique name generated by the compiler for the debugger. The compiler always generates unique names for subprograms declared in library package specifications, because the names might later be overloaded in the package body. Unique names are generated for task accept statements and subprograms declared in other places only if the task accept statements or subprograms are actually overloaded.

Overloaded task accept statement names and subprogram names are distinguished by a suffix consisting of two underscores followed by an integer that uniquely identifies the given symbol. You must use the unique naming notation in debugger commands to uniquely specify a subprogram whose name is overloaded. However, if there is no ambiguity, you do not need to use the unique name, even though one was generated.

C.3.16 CALL Command

With Ada programs, you can use the CALL command reliably only with a subprogram that has been exported. An exported subprogram must be a library subprogram or must be declared in the outermost declarative part of a library package.

The CALL command does not check whether or not the subprogram can be exported, nor does it check the parameter-passing mechanisms that you specify. Note that you cannot use the CALL command to modify the value of a parameter.

A CALL command may result in a deadlock if it is entered when the Ada run-time library is executing. The run-time library routines acquire and release internal locks that allow the routines to operate in a tasking environment. Deadlock can result if a subprogram called from the CALL command requires a resource that has been locked by an executing run-time library routine. To avoid this situation in a nontasking program, enter the CALL command immediately before or after an Ada statement has been executed. However, this approach is not sufficient to assure that deadlock will not occur in a tasking program, as some other task may be executing a run-time library routine at the time of the call. If you must use the CALL command in a tasking program, you can avoid deadlock if the called subprogram does not do any tasking or input-output operations.

C.4 BASIC

The following subtopics describe debugger support for BASIC.

C.4.1 Operators in Language Expressions

Supported BASIC operators in language expressions include:

Kind Symbol Function
Prefix + Unary plus
Prefix - Unary minus (negation)
Infix + Addition, String concatenation
Infix - Subtraction
Infix * Multiplication
Infix / Division
Infix ** Exponentiation
Infix ^ Exponentiation
Infix = Equal to
Infix <> Not equal to
Infix >< Not equal to
Infix > Greater than
Infix >= Greater than or equal to
Infix => Greater than or equal to
Infix < Less than
Infix <= Less than or equal to
Infix =< Less than or equal to
Prefix NOT Bit-wise NOT
Infix AND Bit-wise AND
Infix OR Bit-wise OR
Infix XOR Bit-wise exclusive OR
Infix IMP Bit-wise implication
Infix EQV Bit-wise equivalence

C.4.2 Constructs in Language and Address Expressions

Supported constructs in language and address expressions for BASIC follow:

Symbol Construct
( ) Subscripting
:: Record component selection

C.4.3 Data Types

Supported BASIC data types follow:
BASIC Data Type Operating System Data Type Name
BYTE Byte Integer (B)
WORD Word Integer (W)
LONG Longword Integer (L)
SINGLE F_Floating (F)
DOUBLE D_Floating (D)
GFLOAT G_Floating (G)
DECIMAL Packed Decimal (P)
STRING ASCII Text (T)
RFA (None)
RECORD (None)
Arrays (None)

C.4.4 Compiling for Debugging

If you make changes to a program in the BASIC environment and attempt to compile the program with the /DEBUG qualifier without first saving or replacing the program, BASIC signals the error "Unsaved changes, no source line debugging available." To avoid this problem, save or replace the program, and then recompile the program with the /DEBUG qualifier.

C.4.5 Constants

BASIC constants of the form [radix]"numeric-string"[type] (such as "12.34"GFLOAT) or the form n% (such as 25% for integer 25) are not supported in debugger expressions.

C.4.6 Evaluating Expressions

Expressions that overflow in the BASIC language do not necessarily overflow when evaluated by the debugger. The debugger tries to compute a numerically correct result, even when the BASIC rules call for overflows. This difference is particularly likely to affect DECIMAL computations.

C.4.7 Line Numbers

The sequential line numbers that you refer to in a debugging session and that are displayed in a source code display are those generated by the compiler. When a BASIC program includes or appends code from another file, the included lines of code are also numbered in sequence by the compiler.

C.4.8 Stepping into Routines

The STEP/INTO command is useful for examining external functions. However, if you use this command to stop execution at an internal subroutine or a DEF, the debugger initially steps into run-time library (RTL) routines, providing you with no useful information. In the following example, execution is paused at line 8, at a call to Print_routine:


    ...
->  8  GOSUB Print_routine 
    9  STOP 
    ...
   20  Print_routine: 
   21    IF Competition = Done 
   22      THEN PRINT "The winning ticket is #";Winning_ticket 
   23      ELSE PRINT "The game goes on." 
   24    END IF 
   25  RETURN 

A STEP/INTO command would cause the debugger to step into the relevant RTL code and would inform you that no source lines are available for display. On the other hand, a STEP command alone would cause the debugger to proceed directly to source line 9, past the call to Print_routine. To examine the source code of subroutines or DEF functions, set a breakpoint on the routine label (for example, enter the SET BREAK PRINT_ROUTINE command). You can then suspend execution exactly at the start of the routine (line 20, in this example) and then step directly into the code.


Previous Next Contents Index