hp.com home products and services support and drivers solutions how to buy
cd-rom home
End of Jump to page title
HP OpenVMS systems

Jump to content

HP OpenVMS Calling Standard

HP OpenVMS Calling Standard

Previous Contents Index Mechanism Depth

For all argument mechanisms, the depth field has the value 0 for an exception that is handled by the procedure activation invoking the exception. The exception procedure contains the instruction that either causes the hardware exception or calls LIB$SIGNAL. The depth field of the argument mechanism has positive values for procedure activations calling the one having the exception, for example, 1 for the immediate caller.

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.

Given the same circumstances, the mechanism depth on any given processor type is not necessarily the same as the depth on a different processor type (that is, the depth on a VAX processor may differ from that on an Alpha or Intel Itanium processor, and so on) if any of the following are present:

8.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 HP OpenVMS System Services Reference Manual for the format of the signal argument list.

8.5.3 Coordinating the Handler and Establisher

This section describes the requirements for use of memory, exception synchronization, and continuation of the handler. Use of Memory

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. Exception Synchronization (Alpha Only)

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 VAX or Intel Itanium processors 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. Continuation from Exceptions (Alpha Only)

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 VAX or Itanium 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. Floating-Point Control Status (I64 Only)

Normally the floating-point control status (see Section 4.1.7) of a program is established at the beginning of program execution and remains unchanged throughout execution of the whole program.

However, a procedure (or cooperating group of procedures) may temporarily modify the floating-point control status provided the following rules are followed. Such a procedure must:

8.6 Returning from a Condition Handler

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.

For I64, if the establisher of the handler changes the floating-point control status and either the handler resignals an exception or the handler is called for an unwind exception (see Section 8.7), the handler must reset the floating-point control status to the value saved by the establisher.

8.7 Request to Unwind from a Signal

To unwind, the handler or any procedure that it calls can make a call to SYS$UNWIND. The format is as follows:

SYS$UNWIND(depadr, new_PC)

Argument OpenVMS Usage Type Access Mechanism
depadr integer longword read by reference
new_PC address longword read by reference

Optional number of presignal frames (depth) to be removed.
Optional address of the location to receive control after the unwind operation is completed.

Function Value Returned:
  Success or failure status (see text that follows).

The depadr argument specifies the address of the longword that contains the number of presignal frames (depth) to be removed. The deepest procedure invocation whose frame is not removed is called the target invocation of the unwind. If that number is less than or equal to 0, nothing is to be unwound. The default (address = 0) is to return to the caller of the procedure that established the handler that issued the $UNWIND service. To unwind to the establisher, specify the depth from the call to the handler, which can be found in the CHF$IS_MCH_DEPTH field of the Mechanism Array. When the handler is at depth 0, it can achieve the equivalent of an unwind operation to an arbitrary place in its establisher by altering the PC in its signal_args vector and returning with SS$_CONTINUE, or SS$_CONTINUE64 if the 64-bit signal vector is altered, instead of performing an unwind.

The new_PC argument specifies the location to receive control when the unwinding operation is complete. The default is to continue at the instruction following the call to the last procedure activation that is removed from the stack.

The function value success either is a standard success code (SS$_NORMAL) or it indicates failure with one of the following return status condition values:

If SYS$UNWIND is invoked by a handler that has already invoked SYS$UNWIND, then the effect of the second invocation is undefined.

The unwinding operation occurs when the handler returns to the CHF. Unwinding is done by scanning back through the stack and calling each handler associated with a frame. The handler is called with the exception SS$_UNWIND to perform any application-specific cleanup. If the depth specified includes unwinding the establisher's frame, the current handler is recalled with this unwind exception.

When the target invocation is reached on Alpha or I64 systems, unwind completion depends on the PDSC$V_TARGET_INVO flag of the associated procedure descriptor or unwind information, respectively. If that flag is set to 1, then the handler for that procedure invocation is called; otherwise, no handler is called. Control then resumes in the target invocation.

The call to the handler takes the same form as described in Section 8.5.1 with the following values:

After each handler is called, the stack is logically cut back to the previous frame.

On Alpha or I64 systems, the stack is not actually cut back until after the last handler is called.

The exception vectors are not checked because they are not being removed. Any function value from the handler is ignored.

To specify the value of the top-level function being unwound, the handler should modify the appropriate saved register locations in the mechanism_args vector. They are restored from the mechanism_args vector at the end of the unwind.

Depending on the arguments to SYS$UNWIND, the unwinding operation is terminated as follows:
SYS$UNWIND(0,0) Unwind to the establisher's caller.
SYS$UNWIND( depth,0) Unwind to the establisher at the point of the call that resulted in the exception.
SYS$UNWIND( depth, location) Unwind to the specified procedure activation and transfer to a specified location.

The only recommended values for depth are the default (address of 0), which unwinds to the caller of the establisher, and the value of depth taken from the mechanism vector, which unwinds to the establisher. Other values depend on implementation details that can change at any time.

You can call SYS$UNWIND whether the condition was a software exception signaled by calling LIB$SIGNAL or LIB$STOP or was a hardware exception. Calling SYS$UNWIND is the only way to continue execution after a call to LIB$STOP.

8.7.1 Signaler's Registers

Because the handler is called and can in turn call routines, the actual register values in use at the time of the signal or exception can be scattered on the stack.

On VAX systems, to find registers R2 through FP, a scan of stack frames must be performed starting with the current frame and ending with the call to the handler. During the scan, the last frame found to save a register contains that register's contents at the time of the exception. If no frame saved the register, the register is still active in the current procedure. The frame of the call to the handler can be identified by the return address of SYS$CALL_HANDL+4. In this case, the registers are in the following states:
R0, R1 In mechanism_args
R2--11 Last frame saving it
AP Old AP of SYS$CALL_HANDL+4 frame
FP Old FP of SYS$CALL_HANDL+4 frame
SP Equal to end of signal_args vector+4
PC, PSL At end of signal_args vector

On Alpha or I64 systems, to find the contents of the registers, use the invocation context routines described in Sections 3.5.3 or 4.8.3, respectively.

8.7.2 Unwind Completion

On VAX systems, the values that exist in R0 and R1 when the unwind completes are the values passed implicitly to the unwinder in the mechanism array (see Section If desired, these values can be modified by an exception handler before the unwind is initiated.

On Alpha systems, the values that exist in R0, R1, F0, and F1 when the unwind completes are the values passed implicitly to the unwinder in the mechanism array (see Section If desired, these values can be modified by an exception handler using SYS$SET_RETURN_VALUE before the unwind is initiated. Note that, unlike VAX systems, an Alpha system does not use R1 for returning any type of return values.

On I64 systems, the values that exist in R8, R9, F8, and F9 when the unwind completes are the values passed implicitly to the unwinder in the mechanism array (see Section If desired, these values can be modified by an exception handler using SYS$SET_RETURN_VALUE before the unwind is initiated.

The effect of handler modification of any mechanism vector field other than described above is undefined.

SYS$SET_RETURN_VALUE (Alpha and I64 systems only)

SYS$SET_RETURN_VALUE(mechanism_arg, return_type, return_value)

Argument OpenVMS Usage Type Access Mechanism
mechanism_arg mechanism vector address quadword (unsigned) read by value
return_type integer longword (unsigned) read by reference
return_value buffer scalar read by reference

Address of mechanism vector. If zero, the mechanism vector for the currently active signal will be used. 1
Address of a longword that contains one of the function return signature codes found in Table 5-4. 1
Address of a value of the appropriate type. The referenced value will be read as a longword, quadword, or octaword, depending on the return_type. 1

1If the address of the return_type argument is zero, then the return_value argument is fetched by value and is treated as return-type PSIG$K_FR_U32. This combination of arguments can be used to set a condition code such as SS$_ACCVIO as a return value.

Function Value Returned:
(Success or failure) The given return value is placed in the appropriate fields of the specified mechanism vector, according to the return type.

8.8 GOTO Unwind Operations (Alpha and I64 Systems Only)

A GOTO unwind is a transfer of control that leaves one procedure invocation and continues execution in a prior, currently active procedure invocation. Modular and reliable support of the nonlocal GOTO requires procedure invocations that are terminated to have an opportunity to clean up in an orderly way (just like a procedure that is terminated as a result of an unwind from a condition handler).

Performing a GOTO unwind operation in a thread causes a transfer of control from the location at which the GOTO unwind operation is initiated to a target location in a target invocation. This transfer of control also results in the termination of all procedure invocations, including the invocation in which the unwind request was initiated, up to the target procedure invocation. Thread execution then continues at the target location.

Before control is transferred to the unwind target location, the unwind support code invokes all frame-based handlers that were established by procedure invocations being terminated. These handlers are invoked with an indication of an unwind in progress. This gives each procedure invocation being terminated the chance to perform cleanup processing before its context is lost.

When the target invocation is reached, unwind completion depends on the PDSC$V_TARGET_INVO flag of the associated procedure descriptor (Alpha) or OSSD$V_TARGET_INVO flag of the associated unwind information block (I64). If that flag is set to 1, then the handler for that procedure invocation is called; otherwise, no handler is called.

After all the relevant frame-based handlers have been called and the appropriate frames have been removed from existence, the target invocation's saved context is restored and execution is resumed at the specified location.

A GOTO unwind procedure can be initiated while an exception is active (from within a condition handler) or while no exception is active. If the GOTO unwind transfers control out of an exception handler (resulting in the termination of current handler invocation), it also terminates handling of the corresponding condition (like SYS$UNWIND).


OpenVMS Alpha uses different registers than OpenVMS I64 systems. This section uses the terms RetVal, RetVal2, NewRetVal, and NewRetVal2 to describe the generic unwind operation. The following table translates these terms for each system:
Symbol Alpha Systems I64 Systems
RetVal R0 R8
RetVal2 R1 R9
NewRetVal New_R0 New_R8
NewRetVal2 New_R1 New_R9

A thread can initiate a GOTO unwind operation by calling SYS$GOTO_UNWIND_64, defined as:

SYS$GOTO_UNWIND_64(target_invo, target_pc, NewRetVal, NewRetVal2)

On Alpha systems, the following backward compatible form is also provided:

SYS$GOTO_UNWIND(target_invo, target_pc, New_R0, New_R1)

Argument OpenVMS Usage Type Access Mechanism
target_invo invo_handle longword or quadword (unsigned) 1 read by reference
target_pc address longword or quadword (unsigned) 1 read by reference
NewRetVal quadword_unsigned quadword (unsigned) read by reference
NewRetVal2 quadword_unsigned quadword (unsigned) read by reference

1Type is longword (unsigned) for SYS$GOTO_UNWIND; quadword (unsigned) for SYS$GOTO_UNWIND_64

Previous Next Contents Index