HP OpenVMS Systems Documentation |
HP Fortran for OpenVMS
|
Previous | Contents | Index |
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:
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:
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.
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:
CHF$_xxxxxxx |
For example:
CHF$_IH_MCH_SAVR0 |
FOR$_error |
For example:
FOR$_INPCONERR |
LIB$_condition |
For example:
LIB$_INSVIRMEM |
MTH$_condition |
For example:
MTH$_SQUROONEG |
SS$_status |
For example:
SS$_BADPARAM |
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:
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:
Execution can be affected in a number of ways, such as:
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.
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 |
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.
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 |
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.
Previous | Next | Contents | Index |