Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Trapping RTL errors

ereisch
New Contributor II
668 Views

Any update by chance on the feature request in this post? https://software.intel.com/en-us/forums/intel-fortran-compiler-for-linux-and-mac-os-x/topic/270668

A quick recap: internal run-time library errors (such as invalid I/O namelist reads, array indexing out-of-bounds, and other "internal" problems) will print a useful stack trace and terminate program execution.  It would be helpful if one could either register a callback which could be executed prior to the exit() call, or raising a signal which could have a user-defined handler registered with the kernel.  This would allow graceful shutdown of things like child-processes or sockets.  I understand the signal-raising method could be difficult since it could leave the RTL in an undefined state if the user tries to do other library-involved operations as part of their handler function.

If the feature hasn't made its way in yet, is there a library-provided function which we can write and link-in an alternative to (with an equivalent prototype) to override the RTL's internal error termination function?

Thanks in advance

0 Kudos
1 Solution
Steven_L_Intel1
Employee
668 Views
0 Kudos
10 Replies
Steven_L_Intel1
Employee
669 Views

Take a look at ESTABLISHQQ.

0 Kudos
ereisch
New Contributor II
668 Views

That appears to be exactly what I needed thanks.  The documentation is a little unclear as to the prototype for the handler function though.  From the example, it appears as though the parameter data types for the handler function are INT, LOGICAL, CHAR(*), and, INT, and it appears as though the size of the last parameter is the word size of the program, but are the first two INT*4 and LOGICAL*4?

0 Kudos
Steven_L_Intel1
Employee
668 Views

They are INTEGER(4) and LOGICAL(4), or default integer and logical. The documentation really ought to include the prototype - I'll ask that that be done. Here's the interface from ifestablish.f90:

    abstract interface

        function establishqq_handler (error_code, continuable, message_string, context)

        import
        ! Function result that indicates whether or not the condition was handled.
        ! .TRUE. means that the handler took action and execution should continue if possible;
        ! .FALSE. means that the handler wishes the RTL to do what it would normally do with this condition.
        !
        logical :: establishqq_handler
    
        ! Arguments
        !
        integer,      intent(in) :: error_code         ! RTL error code from IOSTAT table
        logical,      intent(in) :: continuable        ! .TRUE. if condition is continuable
        character(*), intent(in) :: message_string     ! Formatted message string as in ERRMSG/IOMSG
        integer(INT_PTR_KIND()), intent(in) :: context ! Address-sized integer as passed in to call to ESTABLISHQQ
                                                       ! For whatever purpose the programmer desires.  The value is
                                                       ! saved, so changes after the establish call have no effect.
        end function establishqq_handler

 

One thing I see here now (and I have only myself to blame because I wrote this) is that the first two arguments ought to have their kinds explicitly specified using the kinds declared in ISO_FORTRAN_ENV. I'll ask that that be done. Otherwise there could be problems if the program was compiled with different options for integer and logical size.

0 Kudos
ereisch
New Contributor II
668 Views

Ok, thanks.  Last question -- The guide specifies that a C/C++ routine can be used if the ISO_C_BINDINGS module features are used -- does this mean if you use the C bindings to specify the prototype of the handler function, the library will call the C/C++ routine directly, or is this implying a Fortran wrapper needs to be called, and the wrapper can call the C/C++ routine using the bindings module?

0 Kudos
Steven_L_Intel1
Employee
668 Views

That text (which I didn't write!) is incorrect. The module ISO_C_BINDING (no S at the end) has nothing to do with calling procedures. But yes, if you choose to implement the handler routine in some other language, it will be called directly - just make sure that it is interoperable with the interface shown. Note that since one of the arguments is CHARACTER, a hidden length will be passed. (This length is "size_t", passed by value, after all the other arguments.)

0 Kudos
ereisch
New Contributor II
668 Views

It doesn't seem as though the ESTABLISHQQ function can be resolved if you have "-assume nounderscore" specified on your compile line.  If I duplicate the interface found in ifestablish.f90 in my source and append the underscore to the interface, and then manually append the underscore when I call the function, it links successfully.

0 Kudos
Steven_L_Intel1
Employee
668 Views

The better approach is to add to the interface for ESTABLISHQQ:

!DEC$ ATTRIBUTES DEFAULT :: ESTABLISHQQ

I will ask that this be corrected. It's actually a bit worse than this, as the library routine should be called for_establishqq or something like that. Sorry for the problems.

0 Kudos
ereisch
New Contributor II
668 Views

It should be noted that the need for the workaround:

!DEC$ ATTRIBUTES DEFAULT :: ESTABLISHQQ

...is still a bug in ifort version 18.0.5.

0 Kudos
jimdempseyatthecove
Honored Contributor III
668 Views

Steve,

Could you suggest to Intel that they a practical example to illustrate its use. An example I would like to see would be a divide by 0 handler where you can insert a desired result. If possible, extend this to a div/0 within a vectorized routine as well.

An example would be in a particle simulation where two particles co-reside.

Jim Dempsey

0 Kudos
Steve_Lionel
Honored Contributor III
668 Views

Jim, that's not possible using ESTABLISHQQ. You could create a routine that does this sort of recovery using the facilities in the IEEE_xxx modules.

0 Kudos
Reply