[an error occurred while processing this directive]

HP OpenVMS Systems Documentation

Content starts here

HP OpenVMS Calling Standard


Previous Contents Index

8.4.1 Establishing a Condition Handler

On VAX systems, the association of a handler with a procedure invocation is dynamic and can be changed or reverted to the caller's handler during execution, but this is not supported for languages that implicitly provide their own handlers.

Each procedure activation can have an associated condition handler, using the first longword in its stack frame. Initially, the first longword (longword 0) contains the value 0, indicating no handler. You establish a handler by moving the address of the handler's procedure entry point mask to the establisher's stack frame.

On VAX systems, the following code establishes a condition handler:


     MOVAB handler_entry_point,0(FP)


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

Each procedure, other than an Alpha null frame procedure, can have a condition handler potentially associated with it, which is identified by the HANDLER_VALID, STACK_HANDLER, or REG_HANDLER fields of the associated procedure descriptor on an Alpha system, or the handler field in the associated unwind information block on an I64 system. You establish a handler by including the procedure value of the handler procedure in that field. (See Sections 3.4.1, 3.4.4, and A.4.1.)

In addition, the OpenVMS operating system on all processors provides three statically allocated exception vectors for each access mode of a process. These vectors are available to declare condition handlers that take precedence over any handlers declared at the procedure level. For example, the vectors are used to allow a debugger to monitor all exceptions and for the system to establish a last-chance handler. Because these handlers do not obey the procedure nesting rules, do not use them with modular code. Instead, use frame-based handlers.

8.4.2 Reverting to the Caller's Handling

On VAX systems, reverting to the caller's handling deletes the condition handler associated with the current procedure activation. You do this by clearing the handler address in the stack frame.

On VAX systems, the code to revert to the caller's handling is as follows:


     CLRL 0(FP)

On Alpha and I64 systems, there is no means to revert to a caller's handler (unless a language provides emulation of dynamically specified handlers).

8.4.3 Signaling a Condition

The signal operation is the method for indicating the occurrence of an exception condition. To initiate a signal and allow execution to continue after handling the condition, a program calls the LIB$SIGNAL procedure. To initiate a signal but not allow execution to continue at the point of initiation, a program calls the LIB$STOP procedure. The format of the LIB$SIGNAL and LIB$STOP calls are defined as follows:


LIB$SIGNAL(condition-value, argn...)


LIB$STOP(condition-value, argn...)

Argument OpenVMS Usage Type Access Mechanism
condition-value condition longword read by value
argn integer quadword read by value

Arguments:

  condition-value
An OpenVMS condition value.
  argn
Zero or more integer arguments that become the additional arguments of a signal argument vector (see Section 8.5.1.1)

Function Value Returned:

  None.

In both cases, the condition-value argument indicates the condition that is signaled. However, LIB$STOP sets the severity of the condition-value argument to be a severe error. The remaining arguments describe the details of the exception. These are the same arguments used to issue a system message.

Unlike most calls, LIB$SIGNAL and LIB$STOP preserve all registers. Therefore, a debugger can insert a call to LIB$SIGNAL to display the entire state of the process at the time of the exception. Use of LIB$ routines also allows signals to be coded in an assembler language without changing the register usage. This feature of preserving all registers is useful for debugging checks and for gathering statistics. Hardware and system service exceptions behave like calls to LIB$SIGNAL.

8.4.4 Signaling a Condition Using GENTRAP (Alpha and I64 Systems Only)

Alpha and I64 systems each have a special instruction that provides an efficient means to raise a hardware-like exception. These are intended for use especially in low levels of the operating system or in the bootpath sequence when only a limited execution environment is available. Compiled code can also use these instructions to raise common generic exceptions more simply and compactly than by executing a complete LIB$SIGNAL procedure call.

In each case, the special instruction takes an exception code (excp_code) parameter that is passed in a general register; that parameter specifies the particular exception to be raised.

On Alpha systems, the GENTRAP PALcall instruction is used. The excp_code parameter is passed in R16. Interpretation of that parameter is described below.

On I64 systems, the BREAK instruction with an immediate operand of 100001 (hex) is used to implement a GENTRAP operation. The excp_code parameter is passed in R17. Interpretation of that parameter is described below.

If the excp_code value is one of the small integers shown in the first column of Table 8-4, than that value is mapped to a corresponding OpenVMS condition code as shown in the third (Symbol) column of the Table. If the value is negative but not one of the values shown in Table 8-4, then SS$_GENTRAP is raised with the unmapped value included in the signal vector as the first and only qualifier value. Otherwise, a positive value is used directly to raise an exception using that value as the condition value. Note that there is no means to associate any parameters with an exception raised by GENTRAP.

For more information on the Alpha GENTRAP PALcall, see the Alpha Architecture Reference Manual. For more information on the BREAK instruction on the Intel Itanium processors, see the Intel IA-64 Architecture Software Developer's Manual. For more information on Itanium Conventions Defined Codes see Section 8.4.5.

Table 8-4 Exception Codes and Symbols for the GENTRAP Parameter
OpenVMS GENTRAP excp_code Parameter Intel Itanium Conventions Defined Codes (High Bits 000) Symbol Meaning
Alpha and I64 Systems
--1 2 SS$_INTOVF Integer overflow
--2 1 SS$_INTDIV Integer divide by zero
--3   SS$_FLTOVF Floating overflow
--4   SS$_FLTDIV Floating divide by zero
--5   SS$_FLTUND Floating underflow
--6   SS$_FLTINV Floating invalid operand
--7   SS$_FLTINE Floating inexact result
--8 6 SS$_DECOVF Decimal overflow
--9 7 SS$_DECDIV Decimal divide by zero
--10 8, 9, 10 SS$_DECINV Decimal invalid operand
--11 0 SS$_ROPRAND Reserved operand
--12   SS$_ASSERTERR Assertion error
--13 4 SS$_NULPTRERR Null pointer error
--14 11 SS$_STKOVF Stack overflow
--15   SS$_STRLENERR String length error
--16   SS$_SUBSTRERR Substring error
--17   SS$_RANGEERR Range error
--18 3 SS$_SUBRNG Subscript range error
--19   SS$_SUBRNG1 Subscript 1 range error
--20   SS$_SUBRNG2 Subscript 2 range error
--21   SS$_SUBRNG3 Subscript 3 range error
--22   SS$_SUBRNG4 Subscript 4 range error
--23   SS$_SUBRNG5 Subscript 5 range error
--24   SS$_SUBRNG6 Subscript 6 range error
--25   SS$_SUBRNG7 Subscript 7 range error
I64 Systems Only
--26   SS$_CALLUNDEFSYM Call using undefined function symbol
--27   SS$_ARGTYP1 Argument 1 type error
--28   SS$_ARGTYP2 Argument 2 type error
--29   SS$_ARGTYP3 Argument 3 type error
--30   SS$_ARGTYP4 Argument 4 type error
--31   SS$_ARGTYP5 Argument 5 type error
--32   SS$_ARGTYP6 Argument 6 type error
--33   SS$_ARGTYP7 Argument 7 type error
--34   SS$_ARGTYP8 Argument 8 type error
  5 SS$_UNALIGNED Unaligned parameter

8.4.5 Signaling a Condition Using BREAK (I64 Only)

In accordance with the Itanium software conventions, OpenVMS I64 partitions the 21-bit immediate operand values that can occur in a BREAK instruction into the following groups:

  • Immediate operands whose three highest-order bits are 000, which is the range 000000 through 03FFFF (hex). These values are reserved for architected software interrupt codes. The defined software interrupt codes are listed in the second column of Table 8-4. Immediate operands in this range, but not listed in the table, are reserved for future use.
    A code shown in the second column of Table 8-4 is mapped to a corresponding OpenVMS condition code as shown in the third (Symbol) column, which is then raised. (This handling is similar to the handling of a negative excp_code parameter for GENTRAP as described in Section 8.4.4.)
  • Immediate operands whose three highest-order bits are 001, which is the range 040000 (hex) through 07FFFF (hex).
    Operands in this range are reserved for use by applications. If one of these occurs, then SS$_BREAK_APPL is raised with the operand value included as the first (and only) additional argument in the signal argument vector (see Section 8.5.1.1).
  • Immediate operands whose two highest-order bits are 01, which is the range 080000 (hex) through 0FFFFF (hex).
    Operands in this range are reserved for use by debuggers. OpenVMS debugger software uses only immediate operands in the range 080000 (hex) through 0BFFFF (hex). Other debugger software is encouraged, but not required, to use immediate operands in the range 0C0000 (hex) through 0FFFFF (hex).
  • Immediate operands whose highest-order bit is 1, which is the range 100000 (hex) through 1FFFFF (hex).
    Operands in this range are reserved for use within OpenVMS. The value 100001, however, is used to implement an Alpha-compatible GENTRAP operation as described in Section 8.4.4.
    For more information on the Itanium software conventions, see the Itanium® Software Conventions and Runtime Architecture Guide.

8.4.6 Condition Handler Search

The signal procedure examines the two exception vectors first, then examines a system-defined maximum number of previous stack frames, and, if necessary, examines the last-chance exception vector. The exception vectors have three address locations per access mode.

As part of image startup, the system declares a default last-chance handler. This handler is used as a last resort when the normal handlers are not performing correctly. The debugger can replace the default system last-chance handler with its own.

On Alpha and I64 systems, note that the default catchall handler in user mode can be a list of handlers and is not in conflict with this standard.

On OpenVMS systems, in some frame before the call to the main program, the system establishes a default catchall condition handler that issues system messages. In a subsequent frame before the call to the main program, the system usually establishes a traceback handler. These system-supplied condition handlers use the condition-value argument to get the message and then use the remainder of the argument list to format and output the message through the SYS$PUTMSG system service.

If the severity field of the condition-value argument (bits <2:0>) does not indicate a severe error (that is, a value of 4), these default condition handlers return with SS$_CONTINUE. If the severity is a severe error, these default handlers exit the program image with the condition value as the final image status.

The stack search ends when the old frame address is 0 or is not accessible, or when a system-defined maximum number of frames have been examined. If a condition handler is not found, or if all handlers return with a SS$_RESIGNAL or SS$_RESIGNAL64, then the vectored last-chance handler is called.

If a handler returns SS$_CONTINUE or SS$_CONTINUE64, and LIB$STOP was not called, control returns to the signaler. Otherwise, LIB$STOP issues a message indicating that an attempt was made to continue from a noncontinuable exception and exits with the condition value as the final image status.

Figure 8-2 lists all combinations of interaction between condition handler actions, default condition handlers, types of signals, and calls to signal or stop. In this figure, "Cannot Continue" indicates an error that results in the following message:


IMPROPERLY HANDLED CONDITION, ATTEMPT TO CONTINUE FROM STOP.

Figure 8-2 Interaction Between Handlers and Default Handlers


8.5 Properties of Condition Handlers

This section describes the properties of condition handlers for all OpenVMS environments.

8.5.1 Condition Handler Parameters and Invocation

If a condition handler is found on a software-detected exception, the handler is called as follows:


(*handler)(signal_args, mechanism_args)

Argument OpenVMS Usage Type Access Mechanism
signal_args signal vector structure modify by reference
mechanism_args mechanism structure modify by reference

Arguments:

  signal_args
A 32-bit signal argument vector (see Section 8.5.1.1)
  mechanism_args
A mechanism argument vector (see Section 8.5.1.2)

Function Value Returned:

  One of the following status codes: SS$_CONTINUE, SS$_RESIGNAL, SS$_CONTINUE64, SS$_RESIGNAL64. This value is used by the Condition Handling Facility to determine how to proceed next in processing the condition. (See Section 8.6.)

8.5.1.1 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 all OpenVMS systems. When used on Alpha or I64 systems, 32-bit signal argument vectors provide full compatibility with their use on VAX systems. The 64-bit signal argument vectors are used only on Alpha and I64 systems--they have no counterpart and are not recognized on VAX systems.

When a condition handler is called by the Condition Handling Facility (CHF) on Alpha or I64 systems, 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 8.5.1.2.2 and Section 8.5.1.2.3).

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 8-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 8-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.

On I64 systems, the value used for the PS is the low half of a fabricated Alpha-like processor status register that contains IPL, CM, CSW, and IP fields.

Figure 8-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 8.5.1.2.2 and Section 8.5.1.2.3). 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 or I64 PC and PS values.

Figure 8-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:

  • The value of the length field in the 64-bit form (the number of quadwords following the CHF64$L_SIGNAL64 field) is equal to the value of the length field in the 32-bit form (the number of longwords following the CHF$L_SIG_ARGS field).
  • The condition value, any related arguments, and the PC and PS values in the 32-bit form are the same as the values in the 64-bit form truncated to 32 bits.

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:

  • Assuming a 32-bit form, compare the contents of the CHF$L_SIG_NAME field (equivalently CHF64$L_SIGNAL64) with the value SS$_SIGNAL64. If equal, then the 64-bit form is present; otherwise, the 32-bit form is present.
  • Assuming a 64-bit form, compare the contents of the CHF64$L_SIGNAL64 field with the value SS$_SIGNAL64. If equal, then the 64-bit form is present; otherwise, the 32-bit form is present.


Previous Next Contents Index