HP OpenVMS Systems Documentation

Content starts here

HP OpenVMS Debugger Manual

Previous Contents Index

14.3.2 Specific Differences Among Languages

This section lists some of the differences you should keep in mind when debugging in various languages. Included are differences that are affected by the SET LANGUAGE command and other differences (for example, language-specific initialization code and predefined breakpoints).

This section is not intended to be complete. See the debugger's online help (type HELP Language) and your language documentation for complete details. Default Radix

The default radix for entering and displaying integer data is decimal for most languages.

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

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

Use the SET RADIX command to establish a new default radix. Evaluating Language Expressions

Several debugger commands and constructs evaluate language expressions:

  • WHEN clauses, which are used with the SET BREAK, SET TRACE, and SET WATCH commands

When processing these commands, the debugger evaluates language expressions in the syntax of the current language and in the current radix as discussed in Section 4.1.6. At each execution (not when you enter the command), the debugger checks the syntax of any expressions in WHEN or DO clauses, and then evaluates them.

Note that operators vary widely among different languages. For example, the following two commands evaluate equivalent expressions in Pascal and Fortran, respectively:

DBG> SET WATCH X WHEN (Y < 5)       ! Pascal

Assume that the language is set to Pascal and you have entered the first (Pascal) command. You now step into a Fortran routine, set the language to Fortran, and resume execution. While the language is set to Fortran, the debugger is not able to evaluate the expression (Y < 5). As a result, it sets an unconditional watchpoint and, when the watchpoint is triggered, returns a syntax error for the < operator.

This type of discrepancy can also occur if you use commands that evaluate language expressions in debugger command procedures and initialization files.

When the language is set to BLISS, the debugger processes language expressions that contain variable names (or other address expressions) differently than when it is set to another language. See Section 4.1.6 for details. Arrays and Records

The syntax for denoting array elements and record components (if applicable) varies among languages.

For example, some languages use brackets ([]), and others use parentheses (( )), to delimit array elements.

Some languages have zero-based arrays. Some languages have one-based arrays, as in the following example:

   (1,1):       27
   (1,2):       31
   (1,3):       12
   (2,1):       15
   (2,2):       22
   (2,3):       18

For some languages (like Pascal and Ada) the specific array declaration determines how the array is based. Case Sensitivity

Names and language expressions are case sensitive in C. You must specify them exactly as they appear in the source code. For example, the following two commands are not equivalent when the language is set to C:

DBG> SET BREAK screen_io\%LINE 10 Initialization Code

Many programs issue a NOTATMAIN message when a program is brought under debugger control. For example:

           Debugger Banner and Version Number
DBG> RUN prog-name
Language: ADA, Module: MONITOR
Type GO to reach main program

The NOTATMAIN message indicates that execution is paused before the beginning of the main program. This enables you to execute and check some initialization code under debugger control.

The initialization code is created by the compiler and is placed in a special PSECT named LIB$INITIALIZE. For example, in the case of an Ada package, the initialization code belongs to the package body (which might contain statements to initialize variables, and so on). In the case of a Fortran program, the initialization code declares the handler that is needed if you specify the /CHECK=UNDERFLOW or /CHECK=ALL qualifier.

The NOTATMAIN message indicates that, if you do not want to debug the initialization code, you can execute immediately to the beginning of the main program by entering a GO command. You are then at the same point as when you start debugging any other program. Entering the GO command again starts program execution. Predefined Breakpoints

If your program is a tasking program, two breakpoints that are associated with tasking exception events are automatically established when the program is brought under debugger control. These breakpoints are not affected by a SET LANGUAGE command. They are established automatically during debugger initialization when appropriate run-time libraries are present.

To identify these predefined breakpoints, enter the SHOW BREAK command. For example:

Predefined breakpoint on ADA event "EXCEPTION_TERMINATED" for any value
Predefined breakpoint on ADA event "DEPENDENTS_EXCEPTION" for any value
DBG> STEP/OVER Command and Fortran (VAX Only)

On VAX systems, the STEP/OVER command may result in stepping into, not over, Fortran Run-Time Library (RTL) routines. If you are debugging a Compaq Fortran program, and the debugger encounters a Fortran I/O operation such as READ, WRITE, or PRINT, the Fortran compiler calls a Fortran RTL routine to complete the I/O operation. When you issue a STEP command at the call to the RTL routine, the debugger steps into, rather than over, the routine and issues the following error message:

%DEBUG-W-NOSCRLIN, no source line for address nnnnnnnn

The reason is that the debugger steps over routines by searching for a RET instruction to be executed; however, the Fortran compiler deallocates temporary strings used in Fortran RTL I/O routines from the stack in a nonstandard way, without an explicit RET instruction.

To recover from the error message, issue several STEP commands to return the session to the expected line of code. To prevent recurrence of the problem, modify your program to include a temporary variable that stores the results of the function prior to the I/O statement. For example:

    CHARACTER*23 c1, c2
    c1 = c2()                   ! c1 is the temporary variable
    WRITE (*) c1

14.4 Recovering from Stack Corruption

The debugger allocates a certain amount of memory at startup and shares the stack with the user's program. If a user process exception results in exhaustion of resources or corruption of the stack, the debugger may be incapable of regaining control, and the debug session may terminate.

Be aware of this potential behavior after the occurrence of stack corruption messages or warnings about continuing from a severe error. In either case, the integrity of the debug session cannot be guaranteed.

You should try one of the following measures:

  • Change your source code, temporarily or permanently, to reduce resource consumption or lessen the use of stack space
  • Increase quotas
  • Specify a larger stack size when linking your program

14.5 Debugging Exceptions and Condition Handlers

A condition handler is a procedure that the operating system executes when an exception occurs.

Exceptions include hardware conditions (such as an arithmetic overflow or a memory access violation) or signaled software exceptions (for example, an exception signaled because a file could not be found).

Operating system conventions specify how, and in what order, various condition handlers established by the operating system, the debugger, or your own program are invoked---for example, the primary handler, call frame (application-declared) handlers, and so on. Section 14.5.3 describes condition handling when you are using the debugger. See the OpenVMS Run-Time Library Routines Volume for additional general information about condition handling.

Tools for debugging exceptions and condition handlers include the following:

  • The SET BREAK/EXCEPTION and SET TRACE/EXCEPTION commands, which direct the debugger to treat any exception generated by your program as a breakpoint or tracepoint, respectively (see Section 14.5.1 and Section 14.5.2).
  • Several built-in symbols (such as %EXC_NAME), which enable you to qualify exception breakpoints and tracepoints (see Section 14.5.4).
  • The SET BREAK/EVENT and SET TRACE/EVENT commands, which enable you to break on or trace exception events that are specific to Ada, SCAN, or multithread programs (see the corresponding documentation for more information).

14.5.1 Setting Breakpoints or Tracepoints on Exceptions

When you enter a SET BREAK/EXCEPTION or SET TRACE/EXCEPTION command, you direct the debugger to treat any exception generated by your program as a breakpoint or tracepoint. As a result of a SET BREAK/EXCEPTION command, if your program generates an exception, the debugger suspends execution, reports the exception and the line where execution is paused, and prompts for commands. The following example shows the effect:

%SYSTEM-F-INTDIV, arithmetic trap, integer divide by zero at PC=0000066C, PSL=03C00022
break on exception preceding TEST\%LINE 13
     6:         X := 3/Y;

Note that an exception breakpoint (or tracepoint) is triggered even if your program has a condition handler to handle the exception. The SET BREAK/EXCEPTION command causes a breakpoint to occur before any handler can execute (and possibly dismiss the exception). Without the exception breakpoint, the handler will be executed, and the debugger would get control only if no handler dismissed the exception (see Section 14.5.2 and Section 14.5.3).

The following command line is useful for identifying where an exception occurred. It causes the debugger to automatically display the sequence of active calls and the PC value at an exception breakpoint:


You can also create a screen-mode DO display that issues a SHOW CALLS command whenever the debugger interrupts execution. For example:


An exception tracepoint (established with the SET TRACE/EXCEPTION command) is like an exception breakpoint followed by a GO command without an address expression specified.

An exception breakpoint cancels an exception tracepoint, and vice versa.

To cancel exception breakpoints or tracepoints, use the CANCEL BREAK/EXCEPTION or CANCEL TRACE/EXCEPTION command, respectively.

14.5.2 Resuming Execution at an Exception Breakpoint

When an exception breakpoint is triggered, execution is paused before any application-declared condition handler is invoked. When you resume execution from the breakpoint with the GO, STEP, or CALL commands, the behavior is as follows:

  • Entering a GO command without an address-expression parameter, or entering a STEP command, causes the debugger to resignal the exception. The GO command enables you to observe which application-declared handler, if any, next handles the exception. The STEP command causes you to step into that handler (see the next example).
  • Entering a GO command with an address-expression parameter causes execution to resume at the specified location, which inhibits the execution of any application-declared handlers.
  • A common debugging technique at an exception breakpoint is to call a dump routine with the CALL command (see Chapter 13). When you enter the CALL command at an exception breakpoint, no breakpoints, tracepoints, or watchpoints that were previously set within the called routine are active, so that the debugger does not lose the exception context. After the routine has executed, the debugger prompts for input. Entering a GO or STEP command at this point causes the debugger to resignal the exception.

The following Fortran example shows how to determine the presence of a condition handler at an exception breakpoint and how a STEP command, entered at the breakpoint, enables you to step into the handler.

At the exception breakpoint, the SHOW CALLS command indicates that the exception was generated during a call to routine SYS$QIOW:

%SYSTEM-F-SSFAIL, system service failure exception, status=0000013C, PC=7FFEDE06, PSL=03C00000
break on exception preceding SYS$QIOW+6
module name  routine name       line       rel PC    abs PC
              SYS$QIOW                         00000006  7FFEDE06
*EXC$MAIN     EXC$MAIN            23      0000003B  0000063B

On VAX processors, the following SHOW STACK command indicates that no handler is declared in routine SYS$QIOW. However, one level down the call stack, routine EXC$MAIN has declared a handler named SSHAND:

stack frame 0 (2146296644)
    condition handler: 0
       SPA:            0
       S:              0
       mask:           ^M<R2,R3,R4,R5,R6,R7,R8,R9,R10,R11>
       PSW:            0020 (hexadecimal)
    saved AP:          2146296780
    saved FP:          2146296704
    saved PC:          EXC$MAIN\%LINE 25
stack frame 1 (2146296704)
    condition handler: SSHAND
       SPA:            0
       S:              0
       mask:           ^M<R11>
       PSW:            0000 (hexadecimal)
    saved AP:          2146296780
    saved FP:          2146296760
    saved PC:          SHARE$DEBUG+2217

At this exception breakpoint, entering a STEP command enables you to step directly into condition handler SSHAND:

stepped to routine SSHAND
 module name  routine name    line     rel PC    abs PC
*SSHAND       SSHAND            2    00000002  00000642
----- above condition handler called with exception 0000045C:
%SYSTEM-F-SSFAIL, system service failure exception, status=0000013C, PC=7FFEDE06, PSL=03C00000
----- end of exception message
              SYS$QIOW                 00000006  7FFEDE06
*EXC$MAIN     EXC$MAIN         23      0000003B  0000063B

The debugger symbolizes the addresses of condition handlers into names if that is possible. However, note that with some languages, exceptions are first handled by a Run-Time Library (RTL) routine, before any application-declared condition handler is invoked. In such cases, the address of the first condition handler might be symbolized to an offset from an RTL shareable image address.

14.5.3 Effect of the Debugger on Condition Handling

When you run your program with the debugger, at least one of the following condition handlers is invoked, in the order given, to handle any exceptions caused by the execution of your program:

  1. Primary handler
  2. Secondary handler
  3. Call-frame handlers (application-declared)---also known as stack handlers
  4. Final handler
  5. Last-chance handler
  6. Catchall handler

A handler can return one of the following three status codes to the Condition Handling Facility:

  • SS$_RESIGNAL---The operating system searches for the next handler.
  • SS$_CONTINUE---The condition is assumed to be corrected and execution continues.
  • SS$_UNWIND---The call stack is unwound some number of frames, if necessary, and the signal is dismissed.

For more information about condition handling, see the OpenVMS Programming Concepts Manual. Primary Handler

When you run your program with the debugger, the primary handler is the debugger. Therefore, the debugger has the first opportunity to handle an exception, whether or not the exception is caused by the debugger.

If you enter a SET BREAK/EXCEPTION or SET TRACE/EXCEPTION command, the debugger breaks on (or traces) any exceptions caused by your program. The break (or trace) action occurs before any application-declared handler is invoked.

If you do not enter a SET BREAK/EXCEPTION or SET TRACE/EXCEPTION command, the primary handler resignals any exceptions caused by your program. Secondary Handler

The secondary handler is used for special purposes and does not apply to the types of programs covered in this manual. Call-Frame Handlers (Application-Declared)

Each routine of your program can establish a condition handler, also known as a call-frame handler. The operating system searches for these handlers starting with the routine that is currently executing. If no handler was established for that routine, the system searches for a handler established by the next routine down the call stack, and so on back to the main program, if necessary.

After it is invoked, a handler might perform one of the following actions:

  • It handles the exception, which allows the program to continue execution.
  • It resignals the exception. The operating system then searches for another handler down the call stack.
  • It encounters a breakpoint or watchpoint, which suspends execution at the breakpoint or watchpoint.
  • It generates its own exception. In this case, the primary handler is invoked again.
  • It exits, which terminates program execution. Final and Last-Chance Handlers

These handlers are controlled by the debugger. They enable the debugger to regain control and display the DBG> prompt if no application-declared handler has handled an exception. Otherwise, the debugging session will terminate and control will pass to the DCL command interpreter.

The final handler is the last frame on the call stack and the first of these two handlers to be invoked. The following example shows what happens when an unhandled exception is propagated from an exception breakpoint to the final handler:

%SYSTEM-F-INTDIV, arithmetic trap, integer divide by zero at PC=0000066C, PSL=03C00022
break on exception preceding TEST\%LINE 13
     6:         X := 3/Y;
%SYSTEM-F-INTDIV, arithmetic trap, integer divide by zero at PC=0000066C, PSL=03C00022

In this example, the first INTDIV message is issued by the primary handler, and the second is issued by the final handler, which then displays the DBG> prompt.

The last-chance handler is invoked only if the final handler cannot gain control because the call stack is corrupted. For example:

%SYSTEM-F-ACCVIO, access violation, reason mask=00, virtual address=0000000A, PC=0000319C, PSL=03C00000
%DEBUG-E-LASTCHANCE, stack exception handlers lost, re-initializing stack

The catchall handler, which is part of the operating system, is invoked if the last-chance handler cannot gain control. The catchall handler produces a register dump. This should never occur if the debugger has control of your program, but it can occur if your program encounters an error when running without the debugger.

If, during a debugging session, you observe a register dump and are returned to DCL level ($), contact your Compaq support representative.

14.5.4 Exception-Related Built-In Symbols

When an exception is signaled, the debugger sets the following exception-related built-in symbols:

Symbol Description
%EXC_FACILITY Name of facility that issued the current exception
%EXC_NAME Name of current exception
%ADAEXC_NAME Ada exception name of current exception (for Ada programs only)
%EXC_NUMBER Number of current exception
%EXC_SEVERITY Severity code of current exception

You can use these symbols as follows:

  • To obtain information about the fields of the condition code of the current exception.
  • To qualify exception breakpoints or tracepoints so that they trigger only on certain kinds of exceptions.

The following examples show the use of some of these symbols. Note that the conditional expressions in the WHEN clauses are language-specific.

%SYSTEM-F-ACCVIO, access violation, reason mask=01, virtual address=FFFFFF30, PC=00007552, PSL=03C00000

Previous Next Contents Index