[an error occurred while processing this directive]

HP OpenVMS Systems Documentation

Content starts here

OpenVMS Programming Concepts Manual


Previous Contents Index

8.8.3 Resource Waits and Page Faults

When a process is executing an image, the system can place the process in a wait state until a required resource becomes available, or until a page in its virtual address space is paged into memory. These waits, which are generally transparent to the process, can also be interrupted for the delivery of an AST.

8.9 Examples of Using AST Services

The following is an example of a Compaq Fortran program that finds the process identification (PID) number of any user working on a particular disk and delivers an AST to a local routine that notifies the user that the disk is coming down:


 PROGRAM DISK_DOWN
 ! Implicit none
 ! Status variable
 INTEGER STATUS
 STRUCTURE /ITMLST/
  UNION
   MAP
    INTEGER*2 BUFLEN,
 2            CODE
    INTEGER*4 BUFADR,
 2            RETLENADR
   END MAP
          MAP
    INTEGER*4 END_LIST
   END MAP
  END UNION
 END STRUCTURE
 RECORD /ITMLST/ DVILIST(2),
 2               JPILIST(2)
 ! Information for GETDVI call
 INTEGER PID_BUF,
 2       PID_LEN
 ! Information for GETJPI call
 CHARACTER*7 TERM_NAME
 INTEGER TERM_LEN
 EXTERNAL DVI$_PID,
 2        JPI$_TERMINAL
 ! AST routine and flag
 INTEGER AST_FLAG
 PARAMETER (AST_FLAG = 2)
 EXTERNAL NOTIFY_USER

 INTEGER SYS$GETDVIW,
 2       SYS$GETJPI,
 2       SYS$WAITFR

 ! Set up for SYS$GETDVI
 DVILIST(1).BUFLEN = 4
 DVILIST(1).CODE   = %LOC(DVI$_PID)
 DVILIST(1).BUFADR = %LOC(PID_BUF)
 DVILIST(1).RETLENADR = %LOC(PID_LEN)
 DVILIST(2).END_LIST = 0
 ! Find PID number of process using SYS$DRIVE0
 STATUS = SYS$GETDVIW (,
 2                     ,
 2                     '_MTA0:',       ! device
 2                     DVILIST,        ! item list
 2                     ,,,)
 IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS))
 ! Get terminal name and fire AST
 JPILIST(1).CODE = %LOC(JPI$_TERMINAL)
 JPILIST(1).BUFLEN = 7
 JPILIST(1).BUFADR = %LOC(TERM_NAME)
 JPILIST(1).RETLENADR = %LOC(TERM_LEN)
 JPILIST(2).END_LIST = 0
 STATUS = SYS$GETJPI (,
 2                    PID_BUF,         !process id
 2                    ,
 2                    JPILIST,         !itemlist
 2                    ,
 2                    NOTIFY_USER,     !AST
 2                    TERM_NAME)       !AST arg
 IF (.NOT. STATUS) CALL LIB$SIGNAL(%VAL(STATUS))

 ! Ensure that AST was executed
 STATUS = SYS$WAITFR(%VAL(AST_FLAG))
 IF (.NOT. STATUS) CALL LIB$SIGNAL(%VAL(STATUS))
 END


 SUBROUTINE NOTIFY_USER (TERM_STR)
 ! AST routine that broadcasts a message to TERMINAL
 ! Dummy argument
 CHARACTER*(*) TERM_STR
 CHARACTER*8 TERMINAL
 INTEGER LENGTH
 ! Status variable
 INTEGER STATUS
 CHARACTER*(*) MESSAGE
 PARAMETER (MESSAGE =
 2             'SYS$TAPE going down in 10 minutes')
 ! Flag to indicate AST executed
 INTEGER AST_FLAG

 ! Declare system routines
 INTRINSIC LEN
 INTEGER  SYS$BRDCST,
 2        SYS$SETEF
 EXTERNAL SYS$BRDCST,
 2        SYS$SETEF,
 2        LIB$SIGNAL
 ! Add underscore to device name
 LENGTH = LEN (TERM_STR)
 TERMINAL(2:LENGTH+1) = TERM_STR
 TERMINAL(1:1) = '_'

 ! Send message
 STATUS = SYS$BRDCST(MESSAGE,
 2                   TERMINAL(1:LENGTH+1))
 IF (.NOT. STATUS) CALL LIB$SIGNAL(%VAL(STATUS))
 ! Set event flag
 STATUS = SYS$SETEF (%VAL(AST_FLAG))
 IF (.NOT. STATUS) CALL LIB$SIGNAL(%VAL(STATUS))
 END

The following is an example of a C program setting up an AST:


#module SETAST "SRH X1.0-000"
#pragma builtins

/*
** COPYRIGHT (c) 1992 BY
** COMPAQ COMPUTER CORPORATION, MAYNARD, MASSACHUSETTS.
** ALL RIGHTS RESERVED.
**
** THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
** ONLY  IN  ACCORDANCE  WITH  THE  TERMS  OF  SUCH  LICENSE  AND WITH THE
** INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR  ANY  OTHER
** COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
** OTHER PERSON.  NO TITLE TO AND  OWNERSHIP OF THE  SOFTWARE IS  HEREBY
** TRANSFERRED.
**
** THE INFORMATION IN THIS SOFTWARE IS  SUBJECT TO CHANGE WITHOUT NOTICE
** AND  SHOULD  NOT  BE  CONSTRUED  AS A COMMITMENT BY COMPAQ COMPUTER
** CORPORATION.
**
** COMPAQ ASSUMES NO RESPONSIBILITY FOR THE USE  OR  RELIABILITY OF ITS
** SOFTWARE ON EQUIPMENT THAT IS NOT SUPPLIED BY COMPAQ.
*/

/*
**++
**  Facility:
**
** Examples
**
**  Version: V1.0
**
**  Abstract:
**
** Example of working with the $SETAST call and ASTs.
**
**  Author:
** Steve Hoffman
**
**  Creation Date:  1-Jan-1990
**
**  Modification History:
**--
*/
/*
 *  AST and $SETAST demo
 *  raise the AST shields
 *  request an AST, parameter is 1
 *  request an AST, parameter is 2
 *  lower the shields
 *  <bing1><bing2>
 */
main()
    {
    int retstat = 0;
    int bogus();
    int SYS$SETAST();
    int SYS$DCLAST();

    printf("\ndisabling\n");
    /*
     * $SETAST() returns SS$_WASSET and SS$_WASCLR depending
     * on the previous setting of the AST shield.  Watch out,
     * SS$_WASSET looks like a SUCCESSFUL SS$_ACCVIO.  (ie:
     * a debug EXAMINE/COND shows SS$_WASSET as the error
     * %SYSTEM-S-ACCVIO.  *Real* ACCVIO's never have the "-S-"
     *  code!)
     */
    retstat = SYS$SETAST( 0 );
    printf("\n  disable/ was: %d\n", retstat );

    retstat = SYS$DCLAST( bogus, 1, 0 );
    retstat = SYS$DCLAST( bogus, 2, 0 );
    printf("\ndclast %x\n", retstat );

    printf("\nenabling\n" );
    retstat = SYS$SETAST( 1 );

    /*
     *  and, since we just lowered the shields, the ASTs should hit
     *  in here somewhere....
     */
    printf("\n  enable/ was: %d\n", retstat );

    return( 1 );
    };

/*
 *  and, here's the entire, sophisticated, twisted AST code...
 */
bogus( astprm )
int astprm;
    {
    printf("\nAST tripped.  ast parameter was 0x%x\n\n", astprm);
    return( 1 );
    };


Chapter 9
Condition-Handling Routines and Services

This chapter describes the OpenVMS Condition Handling facility and contains the following sections:

Section 9.1 gives an overview of run-time errors.

Section 9.2 gives an overview of the OpenVMS Condition Handling facility, presenting condition-handling terminology and functionality.

Section 9.3 describes VAX system and Alpha system exceptions, arithmetic exceptions, and unaligned access traps on Alpha systems.

Section 9.4 describes how run-time library routines handle exceptions.

Section 9.5 describes the condition value field and the testing and modifying of values.

Section 9.6 describes the exception dispatcher.

Section 9.7 describes the argument list that is passed to a condition handler.

Section 9.8 describes signaling.

Section 9.9 describes types of condition handlers.

Section 9.10 describes types of actions performed by condition handlers.

Section 9.11 describes messages and how to use them.

Section 9.12 describes how to write a condition handler.

Section 9.13 describes how to debug a condition handler.

Section 9.14 describes several run-time library routines that can be established as condition handlers.

Section 9.15 describes how to establish, write, and debug an exit handler.

9.1 Overview of Run-Time Errors

Run-time errors are hardware- or software-detected events, usually errors, that alter normal program execution. Examples of run-time errors are as follows:

  • System errors---for example, specifying an invalid argument to a system-defined procedure
  • Language-specific errors---for example, in Fortran, a data type conversion error during an I/O operation
  • Application-specific errors---for example, attempting to use invalid data

When an error occurs, the operating system either returns a condition code or value identifying the error to your program or signals the condition code. If the operating system signals the condition code, an error message is displayed and program execution continues or terminates, depending on the severity of the error. See Section 9.5 for details about condition values.

When unexpected errors occur, your program should display a message identifying the error and then either continue or stop, depending on the severity of the error. If you know that certain run-time errors might occur, you should provide special actions in your program to handle those errors.

Both an error message and its associated condition code identify an error by the name of the facility that generated it and an abbreviation of the message text. Therefore, if your program displays an error message, you can identify the condition code that was signaled. For example, if your program displays the following error message, you know that the condition code SS$_NOPRIV was signaled:


%SYSTEM-F-NOPRIV, no privilege for attempted operation

9.2 Overview of the OpenVMS Condition Handling Facility

The operating system provides a set of signaling and condition-handling routines and related system services to handle exception conditions. This set of services is called the OpenVMS Condition Handling facility (CHF). The OpenVMS Condition Handling Facility is a part of the common run-time environment of OpenVMS, which includes run-time library (RTL) routines and other components of the operating system.

The OpenVMS Condition Handling facility provides a single, unified method to enable condition handlers, signal conditions, print error messages, change the error behavior from the system default, and enable or disable detection of certain hardware errors. The RTL and all layered products of the operating system use the CHF for condition handling.

See the OpenVMS Calling Standard for a detailed description of OpenVMS condition handling.

9.2.1 Condition-Handling Terminology

This section defines the terms used to describe condition handling.

exception

An event detected by the hardware or software that changes the normal flow of instruction execution. An exception is a synchronous event caused by the execution of an instruction and often means something generated by hardware. When an exception occurs, the processor transfers control by forcing a change in the flow of control from that explicitly indicated in the currently executing process.

Some exceptions are relevant primarily to the current process and normally invoke software in the context of the current process. An integer overflow exception detected by the hardware is an example of an event that is reported to the process. Other exceptions, such as page faults, are handled by the operating system and are transparent to the user.

An exception may also be signaled by a routine (software signaling) by calling the RTL routines LIB$SIGNAL or LIB$STOP.

condition

An informational state that exists when an exception occurs. Condition is a more general term than exception; a condition implies either a hardware exception or a software-raised condition. Often, the term condition is preferred because the term exception implies an error. Section 9.3.1 further defines the differences between exceptions and conditions.

condition handling

When a condition is detected during the execution of a routine, a signal can be raised by the routine. The routine is then permitted to respond to the condition. The routine's response is called handling the condition.

On VAX systems, an address of 0 in the first longword of a procedure call frame or in an exception vector indicates that a condition handler does not exist for that call frame or vector.

On Alpha systems, the handler valid flag bit in the procedure descriptor is cleared to indicate that a condition handler does not exist.

The condition handlers are themselves routines; they have their own call frames. Because they are routines, condition handlers can have condition handlers of their own. This allows condition handlers to field exceptions that might occur within themselves in a modular fashion.

On VAX systems, a routine can enable a condition handler by placing the address of the condition handler in the first longword of its stack frame.

On Alpha systems, the association of a handler with a procedure is static and must be specified at the time a procedure is compiled (or assembled). Some languages that lack their own exception-handling syntax, however, may support emulation of dynamic specified handlers by means of built-in routines.

If you determine that a program needs to be informed of particular exceptions so it can take corrective action, you can write and specify a condition handler. This condition handler, which receives control when any exception occurs, can test for specific exceptions.

If an exception occurs and you have not specified a condition handler, the default condition handler established by the operating system is given control. If the exception is a fatal error, the default condition handler issues a descriptive message and causes the image that incurred the exception to exit.

To declare or enable a condition handler, use the following system services:

  • Set Exception Vector (SYS$SETEXV)
  • Unwind from Condition Handler Frame (SYS$UNWIND)
  • Declare Change Mode or Compatibility Mode Handler (SYS$DCLCMH)

Parallel mechanisms exist for uniform dispatching of hardware and software exception conditions. Exceptions that are detected and signaled by hardware transfer control to an exception service routine in the executive. Software-detected exception conditions are generated by calling the run-time library routines LIB$SIGNAL or LIB$STOP. Hardware- and software-detected exceptions eventually execute the same exception dispatching code. Therefore, a condition handler may handle an exception condition generated by hardware or by software identically.

The Set Exception Vector (SYS$SETEXV) system service allows you to specify addresses for a primary exception handler, a secondary exception handler, and a last-chance exception handler. You can specify handlers for each access mode. The primary exception vector is reserved for the debugger. In general, you should avoid using these vectored handlers unless absolutely necessary. If you use a vectored handler, it must be prepared for all exceptions occurring in that access mode.

9.2.2 Functions of the Condition Handling Facility

The OpenVMS Condition Handling facility and the related run-time library routines and system services perform the following functions:

  • Establish and call condition-handler routines
    You can establish condition handlers to receive control in the event of an exception in one of the following ways:
    • On VAX systems, by specifying the address of a condition handler in the first longword of a procedure call frame.
      On Alpha systems, the method for establishing a dynamic (that is, nonvectored) condition handler is specified by the language.
    • By establishing exception handlers with the Set Exception Vector (SYS$SETEXV) system service.

    The first of these methods is the preferred way to specify a condition handler for a particular image. The use of dynamic handlers is also the most efficient way in terms of declaration. You should use vectored handlers for special purposes, such as writing debuggers.
    The VAX MACRO programmer can use the following single-move address instruction to place the address of the condition handler in the longword pointed to by the current frame pointer (FP):


    MOVAB     HANDLER,(FP)
    

    You can associate a condition handler for the currently executing routine by specifying an address pointing to the handler, either in the routine's stack frame on VAX systems or in one of the exception vectors. (The MACRO-32 compiler for OpenVMS Alpha systems generates the appropriate Alpha code from this VAX instruction to establish a dynamic condition handler.)
    On VAX systems, the high-level language programmer can call the common run-time library routine LIB$ESTABLISH (see the OpenVMS RTL Library (LIB$) Manual), using the name of the handler as an argument. LIB$ESTABLISH returns as a function value either the address of the former handler established for the routine or 0 if no handler existed.
    On VAX systems, the new condition handler remains in effect for your routine until you call LIB$REVERT or control returns to the caller of the caller of LIB$ESTABLISH. Once this happens, you must call LIB$ESTABLISH again if the same (or a new) condition handler is to be associated with the caller of LIB$ESTABLISH.
    On VAX systems, some languages provide access to condition handling as part of the language. You can use the ON ERROR GOTO statement in BASIC and the ON statement in PL/I to define condition handlers. If you are using a language that does provide access to condition handling, use its language mechanism rather than LIB$ESTABLISH. Each procedure can declare a condition handler.
    When the routine signals an exception, the OpenVMS Condition Handling facility calls the condition handler associated with the routine. See Section 9.8 for more information about exception vectors. Figure 9-5 shows a sample stack scan for a condition handler.
    The following Compaq Fortran program segment establishes the condition handler ERRLOG. Because the condition handler is used as an actual argument, it must be declared in an EXTERNAL statement.


    INTEGER*4 OLD_HANDLER
    EXTERNAL  ERRLOG
       .
       .
       .
    OLD_HANDLER = LIB$ESTABLISH (ERRLOG)
    

    LIB$ESTABLISH returns the address of the previous handler as its function value. If only part of a program unit requires a special condition handler, you can reestablish the original handler by invoking LIB$ESTABLISH and specifying the saved handler address as follows:


    CALL LIB$ESTABLISH (OLD_HANDLER)
    

    The run-time library provides several condition handlers and routines that a condition handler can call. These routines take care of several common exception conditions. Section 9.14 describes these routines.
    On Alpha systems, LIB$ESTABLISH and LIB$REVERT are not supported, though a high-level language may support them for compatibility. (Table 9-4 lists other run-time library routines supported and not supported on Alpha systems.)
  • On VAX systems, remove an established condition-handler routine
    On VAX systems using LIB$REVERT, you can remove a condition handler from a routine's stack frame by setting the frame's handler address to 0. If your high-level language provides condition-handling statements, you should use them rather than LIB$REVERT.
  • On VAX systems, enable or disable the detection of arithmetic hardware exceptions
    On VAX systems, using run-time library routines, you can enable or disable the signaling of floating point underflow, integer overflow, and decimal overflow, which are detected by the VAX hardware.
  • Signal a condition
    When the hardware detects an exception, such as an integer overflow, a signal is raised at that instruction. A routine may also raise a signal by calling LIB$SIGNAL or LIB$STOP. Signals raised by LIB$SIGNAL allow the condition handler either to terminate or to resume the normal flow of the routine. Signals raised by LIB$STOP require termination of the operation that raises the condition. The condition handler will not be allowed to continue from the point of call to LIB$STOP.
  • Display an informational message
    The system establishes default condition handlers before it calls the main program. Because these default condition handlers provide access to the system's standard error messages, the standard method for displaying a message is by signaling the severity of the condition: informational, warning, or error. See Section 9.5 for the definition of the severity field of a condition vector. The system default condition handlers resume execution of the instruction after displaying the messages associated with the signal. If the condition value indicates a severe condition, then the image exits after the message is displayed.
  • Display a stack traceback on errors
    The default operations of the LINK and RUN commands provide a system-supplied handler (the traceback handler) to print a symbolic stack traceback. The traceback shows the state of the routine stack at the point where the condition occurred. The traceback information is displayed along with the messages associated with the signaled condition.
  • Compile customer-defined messages
    The Message utility allows you to define your own exception conditions and the associated messages. Message source files contain the condition values and their associated messages. See Section 9.11.3 for a complete description of how to define your own messages.
  • Unwind the stack
    A condition handler can cause a signal to be dismissed and the stack to be unwound to the establisher or caller of the establisher of the condition handler when it returns control to the OpenVMS Condition Handling facility (CHF). During the unwinding operation, the CHF scans the stack. If a condition handler is associated with a frame, the system calls that handler before removing the frame. Calling the condition handlers during the unwind allows a routine to perform cleanup operations specific to a particular application, such as recovering from noncontinuable errors or deallocating resources that were allocated by the routine (such as virtual memory, event flags, and so forth). See Section 9.12.3 for a description of the SYS$UNWIND system service.
  • Log error messages to a file
    The Put Message (SYS$PUTMSG) system service permits any user-written handler to include a message in a listing file. Such message logging can be separate from the default messages the user receives. See Section 9.11 for a detailed description of the SYS$PUTMSG system service.

9.3 Exception Conditions

Exceptions can be generated by any of the following:

  • Hardware
  • Software

Hardware-generated exceptions always result in conditions that require special action if program execution is to continue.

Software-generated exceptions may result in error or warning conditions. These conditions and their message descriptions are documented in the online Help Message utility and in the OpenVMS system messages documentation. To access online message descriptions, use the HELP/MESSAGE command.

More information on using the Help Message utility is available in OpenVMS System Messages: Companion Guide for Help Message Users. That document describes only those messages that occur when the system is not fully operational and you cannot access Help Message.

Some examples of exception conditions are as follows:

  • Arithmetic exception condition in a user-written program detected and signaled by hardware (for example, floating-point overflow)
  • Error in a user argument to a run-time library routine detected by software and signaled by calling LIB$STOP (for example, a negative square root)
  • Error in a run-time library language-support routine, such as an I/O error or an error in a data-type conversion
  • RMS success condition stating that the record is already locked
  • RMS success condition stating that the created file superseded an existing version

There are two standard methods for a Compaq- or user-written routine to indicate that an exception condition has occurred:

  • Return a completion code to the calling program using the function value mechanism
    Most general-purpose run-time library routines indicate exception conditions by returning a condition value in R0. The calling program then tests bit 0 of R0 for success or failure. This method allows better programming structure, because the flow of control can be changed explicitly after the return from each call. If the actual function value returned is greater than 32 bits, then use both R0 and R1.
    On Alpha systems, if the actual function returned is a floating-point value, the floating-point value is returned in F0, or F0 and F1.
  • Signal the exception condition
    A condition can be signaled by calling the RTL routine LIB$SIGNAL or LIB$STOP. Any condition handlers that were enabled are then called by the CHF. See Figure 9-5 for the order in which CHF invokes condition handlers.
    Exception conditions raised by hardware or software are signaled to the routine identically.
    For more details, see Section 9.8 and Section 9.8.1.


Previous Next Contents Index