|
OpenVMS Programming Concepts Manual
9.4.1.1 Integer Overflow and Floating-Point Overflow
Although the hardware normally detects integer overflow and
floating-point overflow errors, run-time library mathematics routines
are programmed with a software check to trap these conditions before
the hardware signaling process can occur. This means that they call
LIB$SIGNAL instead of allowing the hardware to initiate signaling.
The software check is needed because JSB routines cannot set up
condition handlers. The check permits the JSB mathematics routines to
add an extra stack frame so that the error message and stack traceback
appear as if a CALL instruction had been performed. Because of the
software check, JSB routines do not cause a hardware exception
condition even when the calling program has enabled the detection of
integer overflow. On the other hand, detection of floating-point
overflow is always enabled and cannot be disabled.
If an integer or floating-point overflow occurs during a CALL or a JSB
routine, the routine signals a mathematics-specific error such as
MTH$_FLOOVEMAT (Floating Overflow in Math Library) by calling
LIB$SIGNAL explicitly.
9.4.1.2 Floating-Point Underflow
All mathematics routines are programmed to avoid floating-point
underflow conditions. Software checks are made to determine if a
floating-point underflow condition would occur. If so, the software
makes an additional check:
- If the immediate calling program (CALL or JSB) has enabled
floating-point underflow traps, a mathematics-specific error condition
is signaled.
- Otherwise, the result is corrected to zero and execution continues
with no error condition.
The user can enable or disable detection of floating-point underflow at
run time by calling the routine LIB$FLT_UNDER.
9.4.2 System-Defined Arithmetic Condition Handlers
On VAX systems, you can use the following run-time library routines as
arithmetic condition handlers to enable or disable the signaling of
decimal overflow, floating-point underflow, and integer overflow:
- LIB$DEC_OVER---Enables or disables the signaling of a decimal
overflow. By default, signaling is disabled.
- LIB$FLT_UNDER---Enables or disables the signaling of a
floating-point underflow. By default, signaling is disabled.
- LIB$INT_OVER---Enables or disables the signaling of an integer
overflow. By default, signaling is enabled.
You can establish these handlers in one of two ways:
- Invoke the appropriate handler as a function specifying the first
argument as 1 to enable signaling.
- Invoke the handler with command qualifiers when you compile your
program. (Refer to your program language manuals.)
You cannot disable the signaling of integer divide-by-zero,
floating-point overflow, and floating-point or decimal divide-by-zero.
When the signaling of a hardware condition is enabled, the occurrence
of the exception condition causes the operating system to signal the
condition as a severe error. When the signaling of a hardware condition
is disabled, the occurrence of the condition is ignored, and the
processor executes the next instruction in the sequence.
The signaling of overflow and underflow detection is enabled
independently for activation of each routine, because the call
instruction saves the state of the calling program's hardware enable
operations in the stack and then initializes the enable operations for
the called routine. A return instruction restores the calling program's
enable operations.
These run-time library routines are intended primarily for high-level
languages, because you can achieve the same effect in MACRO with the
single Bit Set PSW (BISPSW) or Bit Clear PSW (BICPSW) VAX instructions.
These routines allow you to enable and disable detection of decimal
overflow, floating-point underflow, and integer overflow for a portion
of your routine's execution. Note that the VAX BASIC and Compaq Fortran
compilers provide a compile-time qualifier that permits you to enable
or disable integer overflow for your entire routine.
On Alpha systems, certain RTL routines that process conditions do not
exist because the exception conditions defined by the Alpha
architecture differ somewhat from those defined by the VAX
architecture. Table 9-4 lists the run-time library
condition-handling support routines available on VAX systems and
indicates which are supported on Alpha systems.
Table 9-4 Run-Time Library Condition-Handling Support Routines
Routine |
Availability on Alpha Systems |
Arithmetic Exception Support Routines |
LIB$DEC_OVER--Enables or disables signaling of decimal overflow
|
Not supported
|
LIB$FIXUP_FLT--Changes floating-point reserved operand to a specified
value
|
Not supported
|
LIB$FLT_UNDER--Enables or disables signaling of floating-point underflow
|
Not supported
|
LIB$INT_OVER--Enables or disables signaling of integer overflow
|
Not supported
|
General Condition-Handling Support Routines |
LIB$DECODE_FAULT---Analyzes instruction context for fault
|
Not supported
|
LIB$ESTABLISH---Establishes a condition handler
|
Not supported (languages may support for compatibility)
|
LIB$MATCH_COND---Matches condition value
|
Supported
|
LIB$REVERT--Deletes a condition handler
|
Not supported (languages may support for compatibility)
|
LIB$SIG_TO_STOP---Converts a signaled condition to a condition that
cannot be continued
|
Supported
|
LIB$SIG_TO_RET---Converts a signal to a return status
|
Supported
|
LIB$SIM_TRAP---Simulates a floating-point trap
|
Not supported
|
LIB$SIGNAL---Signals an exception condition
|
Supported
|
LIB$STOP---Stops execution by using signaling
|
Supported
|
9.5 Condition Values
Error conditions are identified by integer values called
condition codes or condition values.
The operating system defines condition values to identify errors that
might occur during execution of system-defined procedures. Each
exception condition has associated with it a unique, 32-bit condition
value that identifies the exception condition, and each condition value
has a unique, systemwide symbol and an associated message. The
condition value is used in both methods of indicating exception
conditions, returning a status and signaling.
From a condition value you can determine whether an error has occurred,
which error has occurred, and the severity of the error. Table 9-5
describes the fields of a condition value.
Table 9-5 Fields of a Condition Value
Field |
Bits |
Meaning |
FAC_NO
|
<27:16>
|
Indicates the system facility in which the condition occurred
|
MSG_NO
|
<15:3>
|
Indicates the condition that occurred
|
SEVERITY
|
<2:0>
|
Indicates whether the condition is a success (bit <0> = 1) or a
failure (bit <0> = 0) as well as the severity of the error, if any
|
Figure 9-3 shows the format of a condition value.
Figure 9-3 Format of a Condition Value
Condition Value Fields
severity
The severity of the error condition. Bit <0> indicates success
(logical true) when set and failure (logical false) when clear. Bits
<1> and <2> distinguish degrees of success or failure. The
three bits, when taken as an unsigned integer, are interpreted as
described in Table 9-6. The symbolic names are defined in module
$STSDEF.
Table 9-6 Severity of Error Conditions
Value |
Symbol |
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_INFO
|
Information
|
Execution continues, informational message displayed
|
4
|
STS$K_SEVERE
|
Severe error
|
Execution terminates, no output
|
5
|
|
|
Reserved for Compaq
|
6
|
|
|
Reserved for Compaq
|
7
|
|
|
Reserved for Compaq
|
condition identification
Identifies the condition uniquely on a systemwide basis.
control
Four control bits. Bit <28> inhibits the message associated with
the condition value from being printed by the SYS$EXIT system service.
After using the SYS$PUTMSG system service to display an error message,
the system default handler sets this bit. It is also set in the
condition value returned by a routine as a function value, if the
routine has also signaled the condition, so that the condition has been
either printed or suppressed. Bits <29:31> must be zero; they are
reserved for Compaq.
When a software component completes execution, it returns a condition
value in this format. When a severity value of warning, error, or
severe error has been generated, the status value returned describes
the nature of the problem. Your program can test this value to change
the flow of control or to generate a message. Your program can also
generate condition values to be examined by other routines and by the
command language interpreter. Condition values defined by customers
must set bits <27> and <15> so that these values do not
conflict with values defined by Compaq.
message number
The number identifying the message associated with the error condition.
It is a status identification, that is, a description of the hardware
exception condition that occurred or a software-defined value. Message
numbers with bit <15> set are specific to a single facility.
Message numbers with bit <15> clear are systemwide status values.
facility number
Identifies the software component generating the condition value. Bit
<27> is set for user facilities and clear for Compaq facilities.
9.5.1 Return Status Convention
Most system-defined procedures are functions of longwords, where the
function value is equated to a condition value. In this capacity, the
condition value is referred to as a return status. You
can write your own routines to follow this convention. See
Section 9.14.3 for information about how to change a signal to a return
status. Each routine description in the OpenVMS System Services Reference Manual, OpenVMS RTL Library (LIB$) Manual,
OpenVMS Record Management Utilities Reference Manual, and OpenVMS Utility Routines Manual lists the condition values that can be
returned by that procedure.
9.5.1.1 Testing Returned Condition Values
When a function returns a condition value to your program unit, you
should always examine the returned condition value. To check for a
failure condition (warning, error, or severe error), test the returned
condition value for a logical value of false. The following program
segment invokes the run-time library procedure LIB$DATE_TIME, checks
the returned condition value (returned in the variable STATUS), and, if
an error has occurred, signals the condition value by calling the
run-time library procedure LIB$SIGNAL ( Section 9.8 describes
signaling):
INTEGER*4 STATUS,
2 LIB$DATE_TIME
CHARACTER*23 DATE
STATUS = LIB$DATE_TIME (DATE)
IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL (STATUS))
|
To check for a specific error, test the return status for a particular
condition value. For example, LIB$DATE_TIME returns a success value
(LIB$_STRTRU) when it truncates the string. If you want to take special
action when truncation occurs, specify the condition as shown in the
following example (the special action would follow the IF statement):
INTEGER*4 STATUS,
2 LIB$DATE_TIME
CHARACTER*23 DATE
INCLUDE '($LIBDEF)'
.
.
.
STATUS = LIB$DATE_TIME (DATE)
IF (STATUS .EQ. LIB$_STRTRU) THEN
.
.
.
|
9.5.1.2 Testing SS$_NOPRIV and SS$_EXQUOTA Condition Values
The SS$_NOPRIV and SS$_EXQUOTA condition values returned by a number of
system service procedures require special checking. Any system service
that is listed as returning SS$_NOPRIV or SS$_EXQUOTA can instead
return a more specific condition value that indicates the privilege or
quota in question. Table 9-7 list the specific privilege errors,
and Table 9-8 lists the quota errors.
Table 9-7 Privilege Errors
SS$_NOACNT
|
SS$_NOALLSPOOL
|
SS$_NOALTPRI
|
SS$_NOBUGCHK
|
SS$_NOBYPASS
|
SS$_NOCMEXEC
|
SS$_NOCMKRNL
|
SS$_NODETACH
|
SS$_NODIAGNOSE
|
SS$_NODOWNGRADE
|
SS$_NOEXQUOTA
|
SS$_NOGROUP
|
SS$_NOGRPNAM
|
SS$_NOGRPPRV
|
SS$_NOLOGIO
|
SS$_NOMOUNT
|
SS$_NONETMBX
|
SS$_NOOPER
|
SS$_NOPFNMAP
|
SS$_NOPHYIO
|
SS$_NOPRMCEB
|
SS$_NOPRMGBL
|
SS$_NOPRMMBX
|
SS$_NOPSWAPM
|
SS$_NOREADALL
|
SS$_NOSECURITY
|
SS$_NOSETPRV
|
SS$_NOSHARE
|
SS$_NOSHMEM
|
SS$_NOSYSGBL
|
SS$_NOSYSLCK
|
SS$_NOSYSNAM
|
SS$_NOSYSPRV
|
SS$_NOTMPMBX
|
SS$_NOUPGRADE
|
SS$_NOVOLPRO
|
SS$_NOWORLD
|
|
|
Table 9-8 Quota Errors
SS$_EXASTLM
|
SS$_EXBIOLM
|
SS$_EXBYTLM
|
SS$_EXDIOLM
|
SS$_EXENQLM
|
SS$_EXFILLM
|
SS$_EXPGFLQUOTA
|
SS$_EXPRCLM
|
SS$_EXTQELM
|
Because either a general or a specific value can be returned, your
program must test for both. The following four symbols provide a
starting and ending point with which you can compare the returned
condition value:
- SS$_NOPRIVSTRT---First specific value for SS$_NOPRIV
- SS$_NOPRIVEND---Last specific value for SS$_NOPRIV
- SS$_NOQUOTASTRT---First specific value for SS$_EXQUOTA
- SS$_NOQUOTAEND---Last specific value for SS$_EXQUOTA
The following Compaq Fortran example tests for a privilege error by
comparing STATUS (the returned condition value) with the specific
condition value SS$_NOPRIV and the range provided by SS$_NOPRIVSTRT and
SS$_NOPRIVEND. You would test for SS$_NOEXQUOTA in a similar fashion.
.
.
.
! Declare status and status values
INTEGER STATUS
INCLUDE '($SSDEF)'
.
.
.
IF (.NOT. STATUS) THEN
IF ((STATUS .EQ. SS$_NOPRIV) .OR.
2 ((STATUS .GE. SS$_NOPRIVSTRT) .AND.
2 (STATUS .LE. SS$_NOPRIVEND))) THEN
.
.
.
ELSE
CALL LIB$SIGNAL (%VAL(STATUS))
END IF
END IF
|
9.5.2 Modifying Condition Values
To modify a condition value, copy a series of bits from one longword to
another longword. For example, the following statement copies the first
three bits (bits <2:0>) of STS$K_INFO to the first three bits of
the signaled condition code, which is in the second element of the
signal array named SIGARGS. As shown in Table 9-6, STS$K_INFO
contains the symbolic severity code for an informational message.
! Declare STS$K_ symbols
INCLUDE '($STSDEF)'
.
.
.
! Change the severity of the condition code
! in SIGARGS(2) to informational
CALL MVBITS (STS$K_INFO,
2 0,
2 3,
2 SIGARGS(2),
2 0)
|
Once you modify the condition value, you can resignal the condition
value and either let the default condition handler display the
associated message or use the SYS$PUTMSG system service to display the
message. If your condition handler displays the message, do not
resignal the condition value, or the default condition handler will
display the message a second time.
In the following example, the condition handler verifies that the
signaled condition value is LIB$_NOSUCHSYM. If it is, the handler
changes its severity from error to informational and then resignals the
modified condition value. As a result of the handler's actions, the
program displays an informational message indicating that the specified
symbol does not exist, and then continues executing.
INTEGER FUNCTION SYMBOL (SIGARGS,
2 MECHARGS)
! Changes LIB$_NOSUCHSYM to an informational message
! Declare dummy arguments
INTEGER*4 SIGARGS(*),
2 MECHARGS(*)
! Declare index variable for LIB$MATCH_COND
INTEGER INDEX
! Declare condition codes
INCLUDE '($LIBDEF)'
INCLUDE '($STSDEF)'
INCLUDE '($SSDEF)'
! Declare library procedures
INTEGER LIB$MATCH_COND
INDEX = LIB$MATCH_COND (SIGARGS(2),
2 LIB$NO_SUCHSYM)
! If the signaled condition code is LIB$NO_SUCHSYM,
! change its severity to informational.
IF (INDEX .GT. 0)
2 CALL MVBITS (STS$K_INFO,
2 0,
2 3,
2 SIGARGS(2),
2 0)
SYMBOL = SS$_RESIGNAL
END
|
9.6 Exception Dispatcher
When an exception occurs, control is passed to the operating system's
exception-dispatching routine. The exception dispatcher searches for a
condition-handling routine invoking the first handler it finds and
passes the information to the handler about the condition code and the
state of the program when the condition code was signaled. If the
handler resignals, the operating system searches for another handler;
otherwise, the search for a condition handler ends.
The operating system searches for condition handlers in the following
sequence:
- Primary exception vectors---Four vectors (lists) of one or more
condition handlers; each vector is associated with an access mode. By
default, all of the primary exception vectors are empty. Exception
vectors are used primarily for system programming, not application
programming. The debugger uses the primary exception vector associated
with user mode.
When an exception occurs, the operating system searches the primary
exception associated with the access mode at which the exception
occurred. To enter or cancel a condition handler in an exception
vector, use the SYS$SETEXV system service. Condition handlers that are
entered into the exception vectors associated with kernel, executive,
and supervisor modes remain in effect either until they are canceled or
until you log out. Condition handlers that are entered into the
exception vector associated with user mode remain in effect either
until they are canceled or until the image that entered them exits.
- Secondary exception vectors---A set of exception vectors with the
same structure as the primary exception vectors. Exception vectors are
primarily used for system programming, not application programming. By
default, all of the secondary exception vectors are empty.
- Call frame condition handlers---Each program unit can establish one
condition handler (the address of the handler is placed in the call
frame of the program unit). The operating system searches for condition
handlers established by your program, beginning with the current
program unit. If the current program unit has not established a
condition handler, the operating system searches for a handler that was
established by the program unit that invoked the current program unit,
and so on back to the main program.
- Traceback handler---If you do not establish any condition handlers
and link your program with the /TRACEBACK qualifier of the LINK command
(the default), the operating system finds and invokes the traceback
handler.
- Catchall handler---If you do not establish any condition handlers
and you link your program with the /NOTRACEBACK qualifier to the LINK
command, the operating system finds and invokes the catchall handler.
The catchall handler is at the bottom of the user stack and in the
last-chance exception vector.
- Last-chance exception vectors---A set of exception vectors with the
same structure as the primary and secondary exception vectors.
Exception vectors are used primarily for system programming, not
application programming. By default, the user- and supervisor-mode
last-chance exception vectors are empty. The executive- and kernel-mode
last-chance exception vectors contain procedures that cause a bugcheck
(a nonfatal bugcheck results in an error log entry; a fatal bugcheck
results in a system shutdown). The debugger uses the user-mode
last-chance exception vector, and DCL uses the supervisor-mode
last-chance exception vector.
The search is terminated when the dispatcher finds a condition handler.
If the dispatcher cannot find a user-specified condition handler, it
calls the condition handler whose address is stored in the last-chance
exception vector. If the image was activated by the command language
interpreter, the last-chance vector points to the catchall condition
handler. The catchall handler issues a message and either continues
program execution or causes the image to exit, depending on whether the
condition was a warning or an error condition, respectively.
You can call the catchall handler in two ways:
- If the last-chance exception vector either returns to the
dispatcher or is empty, then it calls the catchall condition handler
and exits with the return status code SS$_NOHANDLER.
- If the exception dispatcher detects an access violation, it calls
the catchall condition handler and exits with the return status code
SS$_ACCVIO.
Figure 9-4 illustrates the exception dispatcher's search of the call
stack for a condition handler.
Figure 9-4 Searching the Stack for a Condition Handler
In cases where the default condition handling is insufficient, you can
establish your own handler by one of the mechanisms described in
Section 9.2.1. Typically, you need condition handlers only if your
program must perform one of the following operations:
- Respond to condition values that are signaled rather than returned,
such as an integer overflow error. ( Section 9.14.3 describes the
system-defined handler LIB$SIG_TO_RET that allows you to treat signals
as return values; Section 9.4.2 describes other useful system-defined
handlers for arithmetic errors.)
- Modify part of a condition code, such as the severity. See
Section 9.5.2 for more information. If you want to change the severity
of any condition code to a severe error, you can use the run-time
library procedure LIB$STOP instead of writing your own condition
handler.
- Add messages to the one associated with the originally signaled
condition code or log the messages associated with the originally
signaled condition code.
|