Previous | Contents | Index |
An exception condition, as the term is used in this chapter, is an event, usually an error, that occurs during the execution of a program and is detected by system hardware or software or by logic in a user application program. To resolve exception conditions, you can create a condition-handler routine.
This chapter addresses error handling only as it relates to the creation and use of condition-handler routines. Condition-handler routines are specific to the OpenVMS operating system. For a general discussion of error handling, see Chapter 7.
Examples of the types of exception conditions detected by system hardware and software are as follows:
When an exception condition is detected by system hardware or software or by your program, that condition is signaled (by means of a signal call) to the OpenVMS Condition-Handling Facility (CHF). The CHF then invokes one or more condition-handler routines that will attempt to either resolve the condition or terminate the processing in an orderly fashion.
The CHF allows a main program and each subprogram that follows it, regardless of call depth, to establish a condition-handler routine (one per program unit). Each of these condition-handler routines can potentially handle any or all software or hardware events that are treated as exception conditions by the user program or by the system hardware or software. More than one condition handler for a given condition can be established by different program units in the call stack (see the OpenVMS Programming Concepts Manual).
The address of the condition handler for a particular program unit is placed in the call frame for that unit in the run-time call stack.
When the program unit returns to its caller, the call frame is removed and the condition handler for that program unit can no longer be accessed by the CHF. Multiple condition handlers can be accessed by the CHF in the processing of a single exception condition signal. A process-wide handler can be established using the SYS$SETEXV system service.
Throughout this chapter, the term program unit refers to an executable Fortran main program, subroutine, or function.
The Condition-Handling Facility (CHF) receives control and coordinates processing of all exception conditions that are signaled to it. The signals are issued under the following circumstances:
In cases where the default condition handling is insufficient (see Section 14.2), you can develop your own handler routines and use the Compaq Fortran intrinsic function LIB$ESTABLISH to identify your handlers to the CHF. Typically, your needs for special condition handling are limited to the following types of operations:
When an exception condition is detected by a system hardware or software component or by a component in the user application program, the component calls the CHF by means of a signal routine (LIB$SIGNAL or LIB$STOP), passing a value to the CHF that identifies the condition. The CHF takes program control away from the routine that is currently executing and begins searching for a condition-handler routine to call. If it finds one, it establishes a call frame on the run-time call stack and then invokes the handler. The handler routine then attempts to deal with the condition.
The sections that follow describe the CHF in detail---how it operates, how user programs can interact with it, and how users can code their own condition-handling routines:
When the system creates a Compaq Fortran user process, it establishes a system-defined condition handler that will be invoked by the CHF under the following circumstances:
When establishing the default handler, the system has two handlers to choose from: the traceback handler and the catchall handler.
The /DEBUG and /TRACEBACK qualifiers---on the FORTRAN and LINK command lines, respectively---determine which default handler is enabled. If you take the defaults for these qualifiers, the traceback handler is established as the default handler. To establish the catchall handler as the default, specify /NODEBUG or /DEBUG=NOTRACEBACK on the FORTRAN command line and /NOTRACEBACK on the LINK command line.
Use the FORTRAN command /SYNCHRONOUS_EXCEPTIONS qualifier to ensure precise exception reporting.
User-program interactions with the CHF are strictly optional and application-dependent. In each program unit, you have the option of establishing (and removing) a single condition handler to handle exceptions that may occur in that program unit or in subsequent subprograms (regardless of call depth). Once a program unit returns to its caller, its call frame is removed and any condition handler that the program unit has established becomes inaccessible.
The condition handler established by the user program can be coded to handle an exception condition signaled either by system hardware, a Compaq Fortran system software component, or the user program itself. User-program signals are issued by means of the LIB$STOP and LIB$SIGNAL routines described in Section 14.3.2.
Although condition handlers offer a convenient and structured approach to handling exception conditions, they can have a significant impact on run-time performance when a condition handler is actually used. For commonly occurring application-specific conditions within a loop, for example, it may be wise to use other methods of dealing with the conditions. The best use of the facility is in large applications in which occasional exception conditions requiring special handling are anticipated.
The following sections describe how to establish and remove condition
handlers and how to signal exception conditions.
14.3.1 Establishing and Removing Condition Handlers
To establish a condition handler, call the LIB$ESTABLISH intrinsic function. (For compatibility with Compaq Fortran 77 for OpenVMS VAX Systems, Compaq 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, as follows:
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 Compaq 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, as follows:
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.3.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.3.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 OpenVMS Run-Time Library Routines Volume.
The CHF uses these parameters to build the signal argument array SIGARGS (see Section 14.5) 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.2.3). Condition values are usually expressed as condition symbols (see Section 10.7.1). Condition symbols have either of the following forms:
fac$_symbol (Compaq-defined) |
fac__symbol (user-defined) |
fac
A facility name prefix.symbol
Identifies a specific condition. (See Table 7-1 for a list of Compaq 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.3.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 OpenVMS Programming Concepts Manual and the 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 Compaq |
The symbolic names for the severity codes are defined in the $STSDEF library module in the Compaq 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.5 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.7).
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 as follows:
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:
A Compaq 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 Alpha systems from OpenVMS VAX systems (see the 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. The contents of SIGARGS are as follows:
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 Alpha 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.6).
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 88-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). The contents of MECHARGS are as follows:
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 |
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 Compaq Fortran Language Reference Manual for more information on the VOLATILE statement.
One way that condition handlers control subsequent execution is by specifying a function return value (symbols defined in library module $SSDEF). Function return values and their effects are defined in Table 14-2.
Symbolic Values | Effects |
---|---|
SS$_CONTINUE | If you assign the function value of the condition handler to SS$_CONTINUE, the handler returns control to the program unit at the statement that signaled the condition (fault) or the statement following the one that signaled the condition (trap). |
SS$_RESIGNAL | If you assign the function value of the condition handler to SS$_RESIGNAL or do not specify a function value (function value of zero), the CHF will search for another condition handler in the call stack. If you modify SIGARGS or MECHARGS before resignaling, the modified arrays are passed to the next handler. |
A condition handler can also request a call stack unwind by calling SYS$UNWIND before returning. Unwinding the call stack:
In this case, any function return values established by condition handlers are ignored by the CHF.
You can unwind the call stack whether the condition was detected by hardware or signaled by means of LIB$SIGNAL or LIB$STOP. Unwinding is the only way to continue execution after a call to LIB$STOP.
A stack unwind is typically made to one of two places:
INCLUDE '($CHFDEF)' RECORD /CHFDEF2/ MECHARGS CALL SYS$UNWIND(MECHARGS.CHF$IS_MCH_DEPTH,) |
CALL SYS$UNWIND(,) |
The actual stack unwind is not performed immediately after the condition handler issues the call to SYS$UNWIND. It occurs when a condition handler returns control to the CHF.
During the actual unwinding of the call stack, SYS$UNWIND examines each frame in the call stack to determine whether a condition handler was declared. If a handler was declared, SYS$UNWIND calls the handler with the condition value SS_$UNWIND (indicating that the stack is being unwound) in the condition name argument of the signal array. When a condition handler is called with this condition value, that handler can perform any procedure-specific clean-up operations that may be required. After the condition handler returns, the call frame is removed from the stack.
The system service SYS$GOTO_UNWIND performs a similar function.
On an example that uses SYS$UNWIND, see Section 14.12.
14.7 Matching Condition Values to Determine Program Behavior
In many condition-handling situations, you may want to respond to an exception condition regardless of the value of the severity code passed in the condition value. To ignore the severity and control fields of a condition value, use the LIB$MATCH_COND routine as a function in the following form:
index = LIB$MATCH_COND(SIGARGS(2),con-1,...con-n) |
index
An integer variable that is assigned a value for use in a subsequent computed GOTO statement.con
A condition value.
The LIB$MATCH_COND function compares bits 27:3 of the value in SIGARGS(2) with bits 27:3 of each specified condition value. If it finds a match, the function assigns the index value according to the position of the matching condition value in the list.
If the match is with the third condition value following SIGARGS(2), then index = 3. If no match is found, index = 0. The value of the index can then be used to transfer control, as in the following example:
INTEGER (KIND=4) FUNCTION HANDL(SIGARGS,MECHARGS) INCLUDE '($CHFDEF)' INCLUDE '($FORDEF)' INCLUDE '($SSDEF)' INTEGER (KIND=4) SIGARGS(*) RECORD /CHFDEF2/ MECHARGS INDEX=LIB$MATCH_COND(SIGARGS(2), FOR$_FILNOTFOU, & FOR$_NO_SUCDEV, FOR$_FILNAMSPE, FOR$_OPEFAI) GO TO (100,200,300,400), INDEX HANDL=SS$_RESIGNAL RETURN ... 100 ! Handle FOR$_FILNOTFOU ... 200 ! Handle FOR$_NO_SUCDEV ... 300 ! Handle FOR$_FILNAMSPE ... 400 ! Handle FOR$_OPEFAI . . . |
If no match is found between the condition value in SIGARGS(2) and any of the values in the list, then INDEX = 0 and control transfers to the next executable statement after the computed GOTO. A match with any of the values in the list transfers control to the corresponding statement in the GOTO list.
If SIGARGS(2) matches the condition symbol FOR$_OPEFAI, control transfers to statement 400.
When it is preferable to detect errors by signaling, but the calling procedure expects a returned status, LIB$SIG_TO_RET may be used by the procedure that signals. LIB$SIG_TO_RET is a condition handler that converts any signaled condition to a return status. The status is returned to the caller of the procedure that established LIB$SIG_TO_RET.
The arguments for LIB$SIG_TO_RET are as follows:
LIB$SIG_TO_RET (sig-args,mch-args) |
sig-args
Contains the address of the signal argument array (see Section 14.5).mch-args
Contains the address of the mechanism argument array (see Section 14.5).
You can establish LIB$SIG_TO_RET as a condition handler by specifying it in a call to LIB$ESTABLISH. You can also establish it by calling it from a user-written condition handler. If LIB$SIG_TO_RET is called from a condition handler, the signaled condition is returned as a function value to the caller of the establisher of that handler when the handler returns to the CHF. When a signaled exception condition occurs, LIB$SIG_TO_RET procedure does the following:
Your calling procedure is then able to test R0 and R1 as if
the called procedure had returned a status. Then the calling procedure
can specify an error recovery action.
14.9 Changing a Signal to a Stop
The routine LIB$SIG_TO_STOP causes a signal to appear as though it had been signaled by a call to LIB$STOP.
LIB$SIG_TO_STOP can be established as a condition handler or called from within a user-written condition handler.
The argument that you passed to LIB$STOP is a 4-byte condition value (see Section 14.3.3). The argument must be passed using the %VAL argument-passing mechanism.
When a signal is generated by LIB$STOP, the severity code is forced to
severe (STS$K_SEVERE) and control cannot be returned to the procedure
that signaled the condition.
14.10 Checking for Arithmetic Exceptions
On OpenVMS Alpha systems, arithmetic exceptions are indicated by the condition code SS$_HPARITH. The signal array for arithmetic exceptions (condition code SS$_HPARITH) is unique to OpenVMS Alpha systems and contains seven longwords (seven INTEGER (KIND=4) array elements):
In the integer register write mask and the floating-point register write mask, where each bit represents a register, any bits set indicate the registers that were targets of the exception. The exception summary indicates the type of exception or exceptions in the first seven bits of that longword, as follows:
Bit | Meaning |
---|---|
0 | Software completion. |
1 | Invalid floating arithmetic, conversion, or comparison. |
2 | Invalid attempt to perform a floating-point divide with a divisor of zero. (Integer divide-by-zero is not reported.) |
3 | Floating-point exponent overflow (arithmetic or conversion). |
4 | Floating-point exponent underflow (arithmetic or conversion). |
5 | Floating-point inexact result (arithmetic or conversion). |
6 | Integer arithmetic overflow or precision overflow during conversion from floating-point to integer. |
To allow precise reporting of exceptions, specify the /SYNCHRONOUS_EXCEPTIONS qualifier on the FORTRAN command line.
If you omit /SYNCHRONOUS_EXCEPTIONS, instructions beyond the instruction causing the exception may have been executed by the time the exception is reported. This causes the PC to be located at a subsequent instruction (inexact exception reporting). Specifying /SYNCHRONOUS_EXCEPTIONS drains the instruction pipeline after appropriate arithmetic instructions, but this slows performance.
Although Compaq Fortran naturally aligns local variables and provides the /ALIGNMENT qualifier to control alignment of fields in a record structures, derived-type structures, or a common block, certain conditions can result in unaligned data (see Section 5.3).
Unaligned data can result in a data alignment trap, which is an exception indicated by the condition code SS$_ALIGN. The OpenVMS operating system fixes up data alignment traps and does not report them to the program unless requested.
To obtain data alignment trap information, your program can call the SYS$START_ALIGN_FAULT_REPORT service.
You can also run the program within the OpenVMS debugger environment to detect the location of any unaligned data by using the SET BREAK/UNALIGNED debugger command (see Section 4.7).
Use the FORTRAN command /SYNCHRONOUS_EXCEPTIONS qualifier to ensure precise exception reporting.
Depending on the type of optimizations that might be applied, use the FORTRAN command /NOOPTIMIZE qualifier to ensure exception reporting.
The example in this section demonstrates the use of condition handlers in typical Fortran procedures.
The following example creates a function HANDLER that tests for integer overflow. The program needs to be compiled using the /CHECK=OVERFLOW, /SYNCHRONOUS_EXCEPTIONS, and (if fixed source form) /EXTEND_SOURCE qualifiers.
! This program types a maximum value for a 4-byte integer and ! then causes an exception with integer overflow, transferring ! control to a condition handler named HANDLER. ! ! Compile with: /CHECK=OVERFLOW ! /SYNCHRONOUS_EXCEPTIONS ! (and if fixed format, /EXTEND_SOURCE) ! ! File: INT_OVR.F90 ! INTEGER (KIND=4) INT4 EXTERNAL HANDLER (1) CALL LIB$ESTABLISH (HANDLER) (2) int4=2147483645 WRITE (6,*) ' Beginning DO LOOP, adding 1 to ', int4 DO I=1,10 INT4=INT4+1 (3) WRITE (6,*) ' INT4 NUMBER IS ', int4 END DO WRITE (6,*) ' The end ...' END PROGRAM ! The function HANDLER that handles the condition SS$_HPARITH INTEGER (KIND=4) FUNCTION HANDLER (SIGARGS, MECHARGS) (4) INTEGER (KIND=4) SIGARGS(*),MECHARGS(*) (5) INCLUDE '($CHFDEF)' INCLUDE '($SSDEF)' RECORD /CHFDEF1/ SIGARGS RECORD /CHFDEF2/ MECHARGS INTEGER INDEX INTEGER LIB$MATCH_COND INDEX = LIB$MATCH_COND(SIGARGS(2), SS$_HPARITH) (6) IF (INDEX .EQ. 0 ) THEN HANDLER = SS$_RESIGNAL ELSE IF (INDEX .GT. 0) THEN WRITE (6,*) '--> Arithmetic exception detected. Now in HANDLER' CALL LIB$STOP(%VAL(SIGARGS(2)),) (7) END IF RETURN END FUNCTION HANDLER |
The program is compiled, linked, and executed as follows:
$ FORTRAN/CHECK=OVERFLOW/SYNCHRONOUS_EXCEPTIONS INT_OVR (8) $ LINK INT_OVR $ RUN INT_OVR Beginning DO LOOP, adding 1 to 2147483645 INT4 NUMBER IS 2147483646 INT4 NUMBER IS 2147483647 (3) --> Arithmetic exception detected. Now in HANDLER %SYSTEM-F-HPARITH, high performance arithmetic trap, Imask=00000000, Fmask=0002023C, summary=1B, PC=00000001, PS=00000001 -SYSTEM-F-FLTINV, floating invalid operation, PC=00000001, PS=00000001 -SYSTEM-F-FLTOVF, arithmetic trap, floating overflow at PC=00000001, PS=00000001 -SYSTEM-F-FLTUND, arithmetic trap, floating underflow at PC=00000001, PS=00000001 TRACE-F-TRACEBACK, symbolic stack dump follows (7) Image Name Module Name Routine Name Line Number rel PC abs PC INT_OVR INT_OVR$MAIN HANDLER 1718 0000023C 0002023C DEC$FORRTL 0 000729F4 000A49F4 ----- above condition handler called with exception 00000504: %SYSTEM-F-HPARITH, high performance arithmetic trap, Imask=00000002, Fmask=00000000, summary=40, PC=000200CC, PS=0000001B -SYSTEM-F-INTOVF, arithmetic trap,integer overflow at PC=000200CC, PS=0000001B ----- end of exception message 0 84C122BC 84C122BC INT_OVR INT_OVR$MAIN INT_OVR$MAIN 19 000000CC 000200CC 0 84D140D0 84D140D0 |
Previous | Next | Contents | Index |