HP OpenVMS Systems Documentation

Content starts here

HP Fortran for OpenVMS
User Manual


Previous Contents Index

14.4.1 Establishing and Removing Condition Handlers

To establish a condition handler, call the LIB$ESTABLISH intrinsic function. (For compatibility with Compaq Fortran 77 for OpenVMS VAX Systems, HP Fortran provides the LIB$ESTABLISH and LIB$REVERT routines as intrinsic functions.)

The form of the call can be as a subroutine or a function reference:


CALL LIB$ESTABLISH (new-handler)

old-handler=LIB$ESTABLISH(new-handler)

new-handler

Specifies the name of the routine to be set up as a condition handler.

old-handler

Receives the address of the previously established condition handler.

LIB$ESTABLISH moves the address of the condition-handling routine into the appropriate process context and returns the previous address of a previously established condition handler.

The handler itself could be user-written or selected from a list of utility functions provided with HP Fortran. The following example shows how a call to establish a user-written handler might be coded:


  EXTERNAL HANDLER
  CALL LIB$ESTABLISH(HANDLER)

In the preceding example, HANDLER is the name of a Fortran function subprogram that is established as the condition handler for the program unit containing these source statements. A program unit can remove an established condition handler in two ways:

  • Issue another LIB$ESTABLISH call specifying a different handler.
  • Issue the LIB$REVERT call.

The LIB$REVERT call has no arguments and can be a subroutine or a function reference:


CALL LIB$REVERT

old-handler=LIB$REVERT()

The use of old-handler for the LIB$REVERT call is the same as for the LIB$ESTABLISH call.

This call removes the condition handler established in the current program unit. Like LIB$ESTABLISH, LIB$REVERT is provided as an intrinsic function.

When the program unit returns to its caller, the condition handler associated with that program unit is automatically removed (the program unit's stack frame, which contains the condition handler address, is removed from the stack).

14.4.2 Signaling a Condition

When a prescribed condition requiring special handling by a condition handler is detected by logic in your program, you issue a condition signal in your program in order to invoke the CHF. A condition signal consists of a call to one of the two system-supplied signal routines in the following forms:


EXTERNAL LIB$SIGNAL, LIB$STOP

CALL LIB$SIGNAL(condition-value, arg, ..., arg)

CALL LIB$STOP(condition-value, arg, ..., arg)

condition-value

An INTEGER (KIND=4) value that identifies a particular exception condition (see Section 14.4.3) and can only be passed using the %VAL argument-passing mechanism.

arg

Optional arguments to be passed to user-established condition handlers and the system default condition handlers. These arguments consist of messages and formatted-ASCII-output arguments (see the VMS Run-Time Library Routines Volume).

The CHF uses these parameters to build the signal argument array SIGARGS (see Section 14.6) before passing control to a condition handler.

Whether you issue a call to LIB$SIGNAL or LIB$STOP depends on the following considerations:

  • If the current program unit can continue after the signal is made, call LIB$SIGNAL. The condition handler can then determine whether program execution continues. After the signal is issued, control is not returned to the user program until one of the condition handlers in the call stack resolves the exception condition and indicates to the CHF that program execution should continue.
  • If the condition does not allow the current program unit to continue, call LIB$STOP. (The only way to override a LIB$STOP signal is to perform an unwind operation. See Section 14.7.)

Figure 14-1 lists all of the possible effects of a LIB$SIGNAL or LIB$STOP call.

Figure 14-1 Effects of Calls to LIB$SIGNAL or LIB$STOP


In Figure 14-1, "cannot continue" indicates an error that results in the following message:


 IMPROPERLY HANDLED CONDITION, ATTEMPT TO CONTINUE FROM STOP

To pass the condition value, you must use the %VAL argument-passing mechanism (see Section 10.3.3). Condition values are usually expressed as condition symbols (see Section 10.8.1). Condition symbols have either of the following forms:


fac$_symbol (HP-defined)


fac__symbol (user-defined)

fac

A facility name prefix.

symbol

Identifies a specific condition. (See Table 7-1 for a list of HP Fortran condition symbols.)

In the following example, a signal call passes a condition symbol used to report a missing required privilege.


CALL LIB$SIGNAL(%VAL(SS$_NOSYSPRV))

You can include additional arguments to provide supplementary information about the error. System symbols such as SS$_NOSYSPRV are defined in the library module $SSDEF.

When your program issues a condition signal, the CHF searches for a condition handler by examining the preceding call frames, in order, until it either finds a procedure that handles the signaled condition or reaches the default condition handler. Condition handling procedures should use SS$_RESIGNAL for conditions they are not intended to handle.

14.4.3 Condition Values and Symbols Passed to CHF

The OpenVMS system uses condition values to indicate that a called procedure has either executed successfully or failed, and to report exception conditions. Condition values are INTEGER (KIND=4) values (see the HP OpenVMS Programming Concepts Manual and the HP OpenVMS Calling Standard for details). They consist of fields that indicate which software component generated the value, the reason the value was generated, and the severity of the condition. A condition value has the following fields:


The facility number field identifies the software component that generated the condition value. Bit 27 = 1 indicates a user-supplied facility; bit 27 = 0 indicates a system facility.

The message number field identifies the condition that occurred. Bit 15 = 1 indicates that the message is specific to a single facility; bit 15 = 0 indicates a system-wide message.

Table 14-1 gives the meanings of values in the severity code field.

Table 14-1 Severity Codes for Exception Condition Values
Code (Symbolic Name) Severity Response
0 (STS$K_WARNING) Warning Execution continues, unpredictable results
1 (STS$K_SUCCESS) Success Execution continues, expected results
2 (STS$K_ERROR) Error Execution continues, erroneous results
3 (STS$K_INFORMATION) Information Execution continues, informational message displayed
4 (STS$K_SEVERE) Severe error Execution terminates, no output
5 - 7 -- Reserved for use by HP

The symbolic names for the severity codes are defined in the $STSDEF library module in the HP Fortran Symbolic Definition Library, FORSYSDEF.

A condition handler can alter the severity code of a condition value---either to allow execution to continue or to force an exit, depending on the circumstances.

The condition value is passed in the second element of the array SIGARGS. (See Section 14.6 for detailed information about the contents and use of the array SIGARGS.) In some cases, you may require that a particular condition be identified by an exact match; each bit of the condition value (31:0) must match the specified condition. For example, you may want to process a floating overflow condition only if its severity code is still 4 (that is, only if a previous handler has not changed the severity code).

In many cases, however, you may want to respond to a condition regardless of the value of the severity code. To ignore the severity and control fields of a condition value, use the LIB$MATCH_COND routine (see Section 14.8).

The FORSYSDEF library contains library modules that define condition symbols. When you write a condition handler, you can specify any of the following library modules, as appropriate, with an INCLUDE statement:

  • $CHFDEF---This library module contains structure definitions for the primary argument list (CHFDEF), the signal array (CHFDEF1), and the mechanism array (CHFDEF2). These symbols have the following form:

    CHF$_xxxxxxx


    For example:


    CHF$_IH_MCH_SAVR0
    
  • $FORDEF---This library module contains definitions for all condition symbols from the HP Fortran library routines. See Table 7-1 for a list of the HP Fortran error numbers (IOSTAT values) associated with these symbols. These symbols have the following form:

    FOR$_error


    For example:


      FOR$_INPCONERR
    
  • $LIBDEF---This library module contains definitions for all condition symbols from the OpenVMS general utility library facility. These symbols have the following form:

    LIB$_condition


    For example:


      LIB$_INSVIRMEM
    
  • $MTHDEF---This library module contains definitions for all condition symbols from the mathematical procedures library. These symbols have the following form:

    MTH$_condition


    For example:


      MTH$_SQUROONEG
    
  • $SSDEF---This library module contains definitions for system services status codes, which are frequently used in HP Fortran condition handlers. These symbols have the following form:

    SS$_status


    For example:


      SS$_BADPARAM
    

For More Information:

14.5 Operations Performed in Condition Handlers

A condition handler responds to an exception by analyzing arguments passed to it and by taking appropriate action. Possible actions taken by condition handlers are:

  • Condition correction
  • Condition reporting
  • Execution control

First, the handler must determine whether it can correct the condition identified by the condition code passed by the signal call. If possible, the handler takes the appropriate corrective action and execution continues. If it cannot correct the condition, the handler can resignal the condition; it can request that another condition handler (associated with an earlier program unit in the call stack) attempt to process the exception.

Condition reporting performed by handlers can involve one or more of the following actions:

  • Maintaining a count of exceptions encountered during program execution.
  • Signaling the same condition again (resignaling) in order to send the appropriate message to your terminal or log file.
  • Changing the severity field of the condition value and resignaling the condition.
  • Signaling a different condition, such as producing a message appropriate to a specific application. (The condition handler must establish the application-specific condition handler using LIB$ESTABLISH and then signal the condition using LIB$SIGNAL.)

Execution can be affected in a number of ways, such as:

  • Continuing from the point of exception. However, if the signal was issued by means of a call to LIB$STOP, the program exits.
  • Returning control (unwinding) to the program unit that established the handler. Execution resumes at the point of the call that resulted in the exception. The handler establishes the function value to be returned by the called procedure.
  • Returning control (unwinding) to the establisher's caller (to the program unit that called the program unit that established the handler). The handler establishes the function value to be returned by the program unit that established the handler.

For More Information:

14.6 Coding Requirements of Condition Handlers

An HP Fortran condition handler is an INTEGER (KIND=4) function that has two argument arrays passed to it by the CHF. To meet these requirements, you could define a condition handler as follows:


  INCLUDE '($CHFDEF)'
  INTEGER (KIND=4)  FUNCTION HANDLER(SIGARGS,MECHARGS)
  INTEGER (KIND=4)  SIGARGS(*)
  RECORD /CHFDEF2/ MECHARGS

The CHF creates the signal and mechanism argument arrays SIGARGS and MECHARGS and passes them to the condition handler. Note that the mechanism vector block differs on OpenVMS I64 and OpenVMS Alpha systems (see the HP OpenVMS Calling Standard).

The signal array (SIGARGS) is used by condition handlers to obtain information passed as arguments in the LIB$SIGNAL or LIB$STOP signal call.

Table 14-2 shows the contents of SIGARGS.

Table 14-2 Contents of SIGARGS
Array Element CHFDEF1 Field Name Contents
SIGARGS(1) CHF$IS_SIG_ARGS Argument count (n)
SIGARGS(2) CHF$IS_SIG_NAME Condition code
SIGARGS(3 to n-1)
.
.
CHF$IS_SIG_ARG1 (first argument) Zero or more additional arguments, specific to the condition code in SIGARGS(2)
SIGARGS( n) None PC (program counter)
SIGARGS( n+1) None PS (processor status), lower 32-bits of the 64-bit OpenVMS processor status
  • The notation n represents the argument count, that is, the number of elements in SIGARGS, not including the first element.
  • The first array element SIGARGS(1) or CHF$IS_SIG_ARGS indicates how many additional arguments are being passed in this array. The count does not include this first element.
  • SIGARGS(2) or CHF$IS_SIG_NAME indicates the signaled condition (condition value) specified by the call to LIB$SIGNAL or LIB$STOP. If more than one message is associated with the exception condition, the condition value in SIGARGS(2) belongs to the first message.
  • SIGARGS(3) or CHF$IS_SIG_ARG1 varies with the type of condition code in SIGARGS(2). This could contain the message description for the message associated with the condition code in SIGARGS(2), including secondary messages from RMS and system services. The format of the message description varies depending on the type of message being signaled. For more information, see the SYS$PUTMSG description in the HP OpenVMS System Services Reference Manual.
    Additional arguments, SIGARGS(n-1), can be specified in the call to LIB$SIGNAL or LIB$STOP (see Section 14.4.2).
  • The second-to-last element, SIGARGS(n), contains the value of the program counter (PC).
    If the condition that caused the signal was a fault (occurring during the instruction's execution), the PC contains the address of that instruction.
    If the condition that caused the signal was a trap (occurring at the end of the instruction), the PC contains the address of the instruction following the call that signaled the condition code.
  • The last element, SIGARGS(n+1), reflects the value of the processor status (PS) at the time the signal was issued.

A condition handler is usually written in anticipation of a particular condition code or set of condition codes. Because handlers are invoked as a result of any signaled condition code, you should begin your handler routine by comparing the condition code passed to the handler (element 2 of SIGARGS) with the condition codes expected by the handler. If the signaled condition code is not an expected code, you should resignal the condition code by equating the function value of the handler to the global symbol SS$_RESIGNAL (see Section 14.7).

The mechanism array (MECHARGS) is used to obtain information about the procedure activation of the program unit that established the condition handler. MECHARGS is a 90-element array, but only integer registers (Rn) and floating-point registers (Fn) are contained beyond element 12 (R0 is in elements 13 and 14 and all registers are 64 bits).

Table 14-3 shows the contents of MECHARGS on OpenVMS Alpha systems.

The contents are essentially the same on I64 and Alpha up to the CHF$IL_MCH_SAVR10_HIGH field name. After that, the I64 registers are saved in the I64 order and the contents of MECHARGS become different. For information about the additional field names for I64, see the HP OpenVMS System Services Reference Manual.

Table 14-3 Contents of MECHARGS on OpenVMS Alpha Systems
INTEGER (KIND=4) Array Element CHFDEF2 Field Name Contents
MECHARGS(1) CHF$IS_MCH_ARGS Argument count
MECHARGS(2) CHF$IS_MCH_FLAGS Flags
MECHARGS(3), MECHARGS(4) CHF$PH_MCH_FRAME Frame address pointer
MECHARGS(5) CHF$IS_MCH_DEPTH Call depth
MECHARGS(6) CHF$IS_MCH_RESVD1 Not used
MECHARGS(7), MECHARGS(8) CHF$PH_MCH_DADDR Handler data address
MECHARGS(9), MECHARGS(10) CHF$PH_MCH_ESF_ADDR Exception stack frame address
MECHARGS(11), MECHARGS(12) CHF$PH_MCH_SIG_ADDR Signal array address
MECHARGS(13), MECHARGS(14) CHF$IH_MCH_SAVR0
CHF$IL_MCH_SAVR0_LOW
CHF$IL_MCH_SAVR0_HIGH
R0
low-order 32 bits
high-order 32 bits
MECHARGS(15), MECHARGS(16) CHF$IH_MCH_SAVR1
CHF$IL_MCH_SAVR1_LOW
CHF$IL_MCH_SAVR10_HIGH
R1
low-order 32 bits
high-order 32 bits
MECHARGS(17) to MECHARGS(42) CHF$IH_MCH_SAVR nn R16-R28
MECHARGS(43), MECHARGS(44) CHF$FH_MCH_SAVF0(2) F0
MECHARGS(45), MECHARGS(46) CHF$FH_MCH_SAVF1(2) F1
MECHARGS(47) to MECHARGS(88) CHF$IH_MCH_SAVF nn(2) F10-F30
MECHARGS(89), MECHARGS(90) CHF$PH_MCH_SIG64_ADDR Address of 64-bit form of signal arrray
  • CHF$IS_MCH_ARGS or MECHARGS(1) contains the argument count of this array in quadwords, not including this first quadword (the value 43).
  • CHF$IS_MCH_FLAGS or MECHARGS(2) contains various flags to communicate additional information. For instance, if bit zero (0) is set, this indicates that the process has already performed a floating-point operation and that the floating-point registers are valid (CHF$S_FPRREGS_VALID=1 and CHF$V_FPRREGS_VALID=0).
  • CHF$PH_MCH_FRAME or MECHARGS(3) and MECHARGS(4) contains the address of the call frame on the stack for the program unit that established the handler.
  • CHF$IS_MCH_DEPTH or MECHARGS(5) contains the number of calls made between the program unit that established the handler and the program unit that signaled the condition code.
  • MECHARGS(6) is not used.
  • CHF$PH_MCH_DADDR or MECHARGS(7) and MECHARGS(8) contain the address of the handler data quadword.
  • CHF$PH_MCH_ESF_ADDR or MECHARGS(9) and MECHARGS(10) contain the address of the handler stack frame.
  • CHF$PH_MCH_SIG_ADDR or MECHARGS(11) and MECHARGS(12) contains the address of the signal array.
  • CHF$IH_MCH_SAVRnn to CHF$IH_MCH_SAVFnn (2) or MECHARGS(13) to MECHARGS(88) contain certain integer and floating-point registers.
  • MECHARGS(89), MECHARGS(90): for information about 64-bit signal arrays, see HP OpenVMS Calling Standard.

Inside a condition handler, you can use any other variables that you need. If they are shared with other program units (for example, in common blocks), make sure that they are declared volatile. This will ensure that compiler optimizations do not invalidate the handler actions. See Section 5.7.3 and the HP Fortran for OpenVMS Language Reference Manual for more information on the VOLATILE statement.

For More Information:

  • On condition values, see Section 14.4.3.
  • On the Itanium architecture, see the Intel Itanium Architecture Software Developer's Manual, Volume 1: Application Architecture.
  • On register use, see the Alpha Architecture Reference Manual and the HP OpenVMS Calling Standard.
  • On condition handler examples, see Section 14.13.


Previous Next Contents Index