HP OpenVMS Systems Documentation
OpenVMS Calling Standard
6.5 Properties of Condition Handlers
This section describes the properties of condition handlers for both
VAX and Alpha environments.
If a condition handler is found on a software-detected exception, the handler is called as follows:
Function Value Returned:
188.8.131.52 Signal Argument Vector
There are two forms of signal argument vector (or signal vector for short): one for use with 32-bit addresses and one for use with 64-bit addresses. The two forms are compatible in that the forms can be distinguished dynamically at run time and, except for the size and offset of fields, are identical in content and interpretation.
The 32-bit signal argument vectors are used on both OpenVMS VAX and OpenVMS Alpha systems. When used on OpenVMS Alpha, 32-bit signal argument vectors provide full compatibility with their use on OpenVMS VAX. The 64-bit signal argument vectors are used only on OpenVMS Alpha---they have no counterpart and are not recognized on OpenVMS VAX systems.
When a condition handler is called by the Condition Handling Facility (CHF) on Alpha, both forms of signal argument vector are available. The first argument is always a reference to a 32-bit form of signal argument vector. A handler that chooses to operate using the 64-bit form must obtain the address of the corresponding 64-bit signal argument vector from the CHF$PH_MCH_SIG64_ADDR field of the mechanism argument vector (see Section 184.108.40.206).
Both forms of signal vector include a length field, a condition value, zero or more parameters that further qualify the condition value, and finally a processor program counter (PC) and program status (PS). For hardware-detected exceptions, the condition value indicates which exception was taken. The PC value gives the address of the instruction that caused the exception or the address of the next instruction, depending on whether the exception was a fault or a trap. For software-detected conditions, the condition value and any associated parameters are copies of the parameters to the call of LIB$SIGNAL or LIB$STOP that initiated exception handling, while the PC is the return address to the caller of that routine.
Note that bits <2:0> of a condition value indicate severity and not what condition is being signaled. Therefore, a handler should examine only the condition identification, that is, condition value bits <27:3>, to determine the cause of the exception. The setting of severity bits <2:0> may vary from time to time even for the same condition. In fact, some handlers might only change the severity of a condition in the signal vector and resignal.
Generally, a handler may validly modify any field of a signal argument vector except for the CHF$L_SIG_ARGS length field or, in the case of a 64-bit signal vector, the CHF64$L_SIGNAL64 field. In particular, a modified signal vector is passed to a subsequent handler if the current handler completes by resignaling. (If the length is modified, the modification is ignored; CHF restores the original length.) It is invalid for a handler to modify both forms of signal argument vector---the effect of doing so is undefined.
The remainder of this section is organized as follows. First, the 32-bit form of signal argument vector is described. Second, the 64-bit form of signal argument is described. Finally, the relationship between the two forms is discussed.
Figure 6-3 shows the format of the 32-bit form of signal argument vector. The CHF$L_SIG_ARGS longword contains the argument vector count, which is the number of remaining longwords in the vector. The CHF$L_SIG_NAME longword contains the condition value. Next are 0 or more longwords that contain additional parameters appropriate to the condition. The remaining two longwords contain the PC and PS values.
Figure 6-3 Signal Argument Vector --- 32-Bit Format
On VAX systems, the value used for the PS is the contents of the VAX processor status longword (PSL).
On Alpha systems, the value used for the PS is the low half of the Alpha processor status register. Furthermore, CHF$IS_SIG_ARGS and CHF$IS_SIG_NAME are aliases for CHF$L_SIG_ARGS and CHF$L_SIG_NAME, respectively.
Figure 6-4 shows the format of the 64-bit form of signal argument vector. The address of this form of signal argument is available only from the CHF$PH_MCH_SIG64_ADDR field of the mechanism argument vector (see Section 220.127.116.11). The CHF64$L_SIG_ARGS field is a longword that contains the number of remaining quadwords in the vector (following the CHF64$L_SIGNAL64 field). The CHF64$L_SIGNAL64 longword contains a special code named SS$_SIGNAL64 whose value is key to distinguishing between a 32-bit and 64-bit form of signal argument vector. The CHF64$Q_SIG_NAME quadword contains a sign-extended condition value. Next are zero or more quadwords that contain additional parameters appropriate to the condition. The remaining two quadwords contain the Alpha PC and PS values.
Figure 6-4 Signal Argument Vector --- 64-Bit Format
When a handler is called, the 32-bit and 64-bit signal argument vectors are closely related as follows:
Note that given a 64-bit signal vector, it is possible to create the corresponding 32-bit signal vector by fetching the low-order longword of each quadword of the 64-bit vector and packing the results together contiguously into a 32-bit vector; other than using the length, no interpretation of the contents is required.
Given the address of a signal argument vector that might be either the 32-bit or 64-bit form, either of the following equivalent tests may be used to distinguish which one is present:
18.104.22.168 Mechanism Argument Vector
The mechanism argument vector for the argument mechanism_args contains information about the machine state when an exception occurs or when a condition is signaled. Therefore, the mechanism argument vector is highly specific to the underlying machine architecture.
On VAX systems, the mechanism format for the argument vectors is shown in Figure 6-5. The first longword contains the argument vector count, which is the number of remaining longwords in the vector. The frame longword contains the contents of the FP in the establisher's context. If the restrictions described in Section 22.214.171.124 are met, the frame can be used as a base from which to access the local storage of the establisher.
The depth longword is a positive count of the number of procedure-activation stack frames between the frame in which the exception occurred and the frame depth that established the handler being called. (For more information about depth, see Section 126.96.36.199.)
The CHF$L_MCH_SAVR0 and CHF$L_MCH_SAVR1 longwords save the state of the R0 and R1 registers, respectively, at the time of the call to LIB$SIGNAL or LIB$STOP. If not modified by a handler during CHF processing, these values will become the values of those registers after completion of CHF processing (either by continuation or by unwinding). These two fields may be modified by a handler to establish different values to be used at CHF completion. Note that the contents of other registers are not available in the mechanism vector and can only be accessed by analysis of the stack. (See Section 6.7.1.)
Figure 6-5 VAX Mechanism Vector Format
If the VAX vector hardware or emulator option is in use, then for hardware-detected exceptions, the vector state is implicitly saved before any condition handler is entered and restored after the condition handler returns. (Save and restore is not required for exceptions initiated by calls to LIB$SIGNAL or LIB$STOP, because there can be no useful vector state at the time of such calls in accordance with the rules for vector register usage in Section 2.1.2.) Thus, a condition handler can make use of the system vector facilities in the same manner as mainline code.
The VAX saved vector state is not directly available to a condition handler. A condition handler that needs to manipulate the vector state to carry out agreements with its callers can call the SYS$RESTORE_VP_STATE service. This service restores the saved state to the vector registers (whether hardware or emulated) and cancels any subsequent restore. The vector state can then be manipulated directly in the normal manner by means of vector instructions. (This service is normally of interest only during processing for an unwind condition.)
On Alpha systems, the 64-bit-wide mechanism array is the argument mechanism in the handler call. The array shown in Figure 6-6 is defined by constant CHF$S_CHFDEF2 at a size of 360 bytes (45 quadwords). Table 6-5 lists and describes the fields.
The CHF$IH_MCH_SAVRnn and CHF$FH_MCH_SAVFnn quadwords save the state of the nonpreserved general and floating registers, respectively, at the time of the call to LIB$SIGNAL or LIB$STOP. If not modified by a handler during CHF processing, these values will become the values of those registers after completion of CHF processing (either by continuation or by unwinding). These fields may be modified by a handler to establish different values to be used at CHF completion.
The CHF$IH_MCH_SAVRnn and CHF$FH_MCH_SAVFnn fields are the only fields of an Alpha mechanism vector that can be validly modified by a handler. The effect of any other modification is undefined. (See also Section 6.7.2.) Note that the contents of the normally preserved registers are not available in the mechanism vector and can only be accessed by analysis of the stack. (See Section 6.7.1.)
Figure 6-6 Alpha Mechanism Vector Format
If a system service gives an exception, the immediate caller of the service is notified at depth = 1. The depth field has a value of - 2 when the condition handler is established by the primary exception vector, a value of - 1 when it is established by the secondary vector, and a value of - 3 when it is established by the last-chance vector.
The Alpha mechanism depth may not be the same as the depth for the same circumstances on a VAX system if any of the following are present:
6.5.2 System Default Condition Handlers
If one of the default condition handlers established by the system is
entered, the handler calls the SYS$PUTMSG system service to interpret
the signal argument list and to output the indicated information or
error message. See the description of SYS$PUTMSG in the OpenVMS System Services Reference Manual
for the format of the signal argument list.
This section describes the requirements for use of memory, exception
synchronization, and continuation of the handler.
Exceptions can be raised and unwind operations (which cause exception handlers to be called) can occur when the current value of one or more variables is in registers rather than in memory. Because of this, a handler, and any descendant procedure called directly or indirectly by a handler, must not access any variables except those explicitly passed to the procedure as arguments or those that exist in the normal scope of the procedure.
This rule can be violated for specific memory locations only by
agreement between the handler and all procedures that might access
those memory locations. A handler that makes such agreements does not
conform to this standard.
The Alpha hardware architecture allows instructions to complete in a different order than that in which they were issued, and for exceptions caused by an instruction to be raised after subsequently issued instructions have been completed.
Because of this, the state of the machine when a hardware exception occurs cannot be assumed with the same precision as it can be assumed on conventional VAX machines unless such precision has been guaranteed by bounding the exception range with the appropriate insertion of TRAPB instructions.
The rules for bounding the exception range follow:
These rules ensure that exceptions are detected in the intended context of the exception handler.
These rules do not ensure that all exceptions are detected
while the procedure within which the exception-causing instruction was
issued is current. For example, if a procedure without an exception
handler is called by a procedure that has an exception handler not
sensitive to invocation depth, an exception detected while that called
procedure is current may have been caused by an instruction issued
while the caller was the current procedure. This means the frame,
designated by the exception-handling information, is the frame that was
current when the exception was detected, not necessarily the frame that
was current when the exception-causing instruction was issued.
The Alpha architecture guarantees neither that instructions are completed in the same order in which they were fetched from memory nor that instruction execution is strictly sequential. Continuation is possible after some exceptions, but certain restrictions apply.
By definition, software-raised general exceptions are synchronous with the instruction stream and can have a well-defined continuation point. Therefore, a handler can request continuation from a software-raised exception. However, since compiler-generated code typically relies on error-free execution of previously executed code, continuing from a software-raised exception might produce unpredictable results and unreliable behavior unless the handler has explicitly fixed the cause of the exception so that it is transparent to subsequent code.
Hardware faults on Alpha processors follow the same rules as the strict interpretation of the conventional VAX rules. Loosely paraphrased, these rules state that if the offending exception is fixed, reexecution of the instruction (as determined from the supplied PC) will yield correct results. This does not imply that instructions following the faulting instruction have not been executed. Therefore, hardware faults can be viewed as similar to software-raised exceptions and can have well-defined continuation points.
Arithmetic traps cannot be restarted because all the information
required for a restart is not available. The most straightforward and
reliable way in which software can guarantee the ability to continue
from this type of exception is by placing appropriate TRAPB
instructions in the code stream. Although this technique does allow
continuation, it must be used with extreme caution because of the
negative effect on application performance.
Condition handlers are invoked by the OpenVMS Condition Handling Facility (CHF). Therefore, the return from the condition handler is to the CHF.
To continue from the instruction following the signal, the handler must return with a function value of either SS$_CONTINUE or SS$_CONTINUE64 (both of which have bit <0> set). If, however, the condition is signaled with a call to LIB$STOP, the image exits. To resignal the condition, the condition handler returns with a function value of either SS$_RESIGNAL or SS$_RESIGNAL64 (both of which have the bit <0> clear).
The difference between SS$_CONTINUE and SS$_CONTINUE64, and similarly between SS$_RESIGNAL and SS$_RESIGNAL64, is of significance only if the handler has made an alteration to the signal vector that is intended to be taken into account by the CHF. When SS$_CONTINUE or SS$_RESIGNAL is returned, then any modification to the 32-bit signal vector is propagated (in sign-extended form) to the corresponding position in the 64-bit vector. When SS$_CONTINUE64 or SS$_RESIGNAL64 is returned, any modification in the 64-bit signal vector is propagated (in truncated form) to the corresponding position in the 32-bit vector. If no modification has been made, then the two forms of continuation or resignal are equivalent.
The algorithm for detecting change is as follows:
To alter the severity of the signal, the handler modifies the low-order three bits of the condition value longword in the signal_args vector and resignals. If the condition handler wants to alter the defined control bits of the signal, the handler modifies bits <31:28> of the condition value and resignals. To unwind, the handler calls SYS$UNWIND and then returns. In this case, the handler function value is ignored.