Compaq Fortran
User Manual for
OpenVMS Alpha Systems


Previous Contents Index


Chapter 14
Condition-Handling Facilities

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.

For More Information:

14.1 Overview of the Condition-Handling Facility

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:

14.2 Default Condition Handler

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.

For More Information:

14.3 User-Program Interactions with the CHF

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


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:


Condition Value 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.

Table 14-1 Severity Codes for Exception Condition Values
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:

For More Information:

14.4 Operations Performed in Condition Handlers

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:

For More Information:

14.5 Coding Requirements of Condition Handlers

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


The notation n represents the argument count, that is, the number of elements in SIGARGS, not including the first element.

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.

For More Information:

14.6 Returning from a Condition Handler

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.

Table 14-2 Condition-Handler Function Return Values
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:

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.

For More Information:

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.

For More Information:

14.8 Changing a Signal to a Return Status

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.

For More Information:

14.11 Checking for Data Alignment Traps

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.

For More Information:

14.12 Condition Handler Example

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
 
 

  1. The routine HANDLER is declared as EXTERNAL.
  2. The main program calls LIB$ESTABLISH to establish the condition handler named HANDLER.
  3. Within the DO loop, the value of variable INT4 is incremented. When the overflow occurs, control transfers to the condition handler.
  4. The condition handler (function HANDLER) is declared as an integer function accepting the signal array and mechanism array arguments.
  5. The library modules $SSDEF and $CHFDEF from FORSYSDEF.TLB are included and the SIGARGS and MECHARGS variables are declared as records. In this case, the structure definitions for the MECHARGS array are not needed, so the $CHFDEF library module is not included.
  6. The condition handler is only intended to handle the condition code SS$_HPARITH. For other conditions, SS$_RESIGNAL is returned, allowing the CHF to look for another condition handler.
  7. If the exception is SS$_HPARITH, the condition handler makes a call to LIB$STOP to:
  8. The program must be compiled using /CHECK=OVERFLOW. Using /SYNCHRONOUS_EXCEPTIONS allows more precise exception reporting. If the program is compiled as fixed-form file, specify the /EXTEND_SOURCE qualifier.


Previous Next Contents Index