Exception Handling

Exception Handling

Still working on my C++ project which has to call Fortran Function :

I use an IEEE_HANDLER in my Fortran Code to catch different exception (here divide by zero).

When a divide by zero occur in my Fortran Code the function in parameter of my IEEE_HANDLER is called.

The problem is, when this function is terminated, I'm unable to continu in my C++ function, even putting a try catch for my Fortran Function.

Example :

C++ Code :

try

{

printf("Before"
);

MyFortranFunction();

printf("After"
);

}

catch (const std::exception& e)

{

printf ("Exception catched
");

}

Fortran Code (Extract from Intel documentation) :

SUBROUTINE MyFortranFunction() BIND(C, name="MyFortranFunction")

use,intrinsic :: ISO_C_BINDING

implicite none

real(C_DOUBLE) :: B

real(C_DOUBLE) :: C

CALL FPE_SETUP

B = 5.0

C = 0.0

B = B/C

print *, 'end of MyFortranFunction'

End Subroutine MyFortranFunction

SUBROUTINE FPE_SETUP
USE IFPORT
IMPLICIT NONE
INTERFACE
SUBROUTINE FPE_HANDLER(SIGNO, SIGINFO)
INTEGER(4), INTENT(IN) :: SIGNO, SIGINFO
END SUBROUTINE
END INTERFACE
INTEGER IR
IR = IEEE_HANDLER('set','division',FPE_HANDLER)
END SUBROUTINE FPE_SETUP

SUBROUTINE FPE_HANDLER(SIG, CODE)
USE IFPORT
IMPLICIT NONE
INTEGER SIG, CODE
IF(CODE.EQ.FPE$ZERODIVIDE) PRINT *,'Occurred divide by zero.'
END SUBROUTINE FPE_HANDLER

Trace generated :

Before

Occurred divide by zero.

Do you have any idea about how to continu after an handle of exception in the Fortran Function ?

Thanks in advance

18 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

Maybe an explanation of the behavior I expect will be more clear for everybody :

I want to call a mathematical Fortran Model from my C++ Project.

If any error occur during the calculation inside the Fortran Model. I want to catch it inside the Fortran code, take the stack trace to know where this error happen and continu the calculation (or stop, depending of the type of error). If I stop, I want to go back to the C++ code and continu the programm after the call of the Fortran Function.

I don't think there's any support for that. However, Fortran 2003 defines a broad set of features for controlling and handling IEEE FP exceptions. That is not supported in version 10.1 but is expected to be in the next major release late this year.

You may want to compile with "-fp-model strict" which may assist you.

Steve - Intel Developer Support

I take a look to the description of "-fp-model strict" but I don't understand well the use of it.
Can you precise me this point ?

By the way, I compile my fortran model with the option -fpe0. But when I call my model function from my C++ code, even if it does a division by zero, it doesn't crash. Is there any reason ? Is this option to specify to crash if any IEEE exception occurs ?

Still thanks for your help.

-fpe0 works only when the main program is in Fortran. You can call FOR_SET_FPE from your Fortran code (see the Intel Fortran documentation about that). This will set the floating point status bits appropriately.

-fp-model strict is used when you are changing the FP environment from the defaults. It tells the compiler not to make assumptions about the FP environment.

Steve - Intel Developer Support

Ok, so I have to specify the option -fp-model strict for compiling and modify the floating point status bits with FOR_SET_FPE inside my Fortran Code to able to raise the exception.
Nevertheless, there is still an open point, how can I handle this exception to generate a stack trace of the exception and continu the treatment ?
I take a look on SIGNALQQ and try this sample of code :

   PROGRAM SIGTEST
USE IFCORE
...
R3 = 0.0E0
STS = SIGNALQQ(MY_HANDLER)
! Cause a divide by zero exception
R1 = 3.0E0/R3
R1 = 1
...
END

INTEGER(4) FUNCTION MY_HANDLER(SIGNUM,EXCNUM)
USE IFCORE
...
EPTRS = GETEXCEPTIONPTRSQQ()
...
CALL TRACEBACKQQ("Application SIGFPE error!",USER_EXIT_CODE=-1,EPTR=EPTRS)
...
MY_HANDLER = 1


END

But unfortunately, I'm unable to link this code with g++ to my C++ project GETEXCEPTIONPTRSQQ is unreferenced : do you know which library I have to link ? I 've already link ifcore and ifort.
I also doubt that with this type of behaviour I will be able to go back to my treatment (here R1 = 1) after the handle of the signal.

If you have any experience on this problem, I will be grateful to have any example.

Many thanks for your help

As documented, GETEXCEPTIONPTRSQQ is a Windows-only routine.

Steve - Intel Developer Support

Effectively I missed this information ...
If you have any other idea to have the behavior I expect...

Try adding -fexceptions

Steve - Intel Developer Support

I add the options "-fexceptions -fp-model strict" and use FOR_SET_FPE function : The exception is raised well for my divide by zero exception in my Fortran Code.

Nevertheless I'm still unable to catch this exception in my C++ code, the program terminated
Try
{
MyFortranFunction
}
catch(...)
{
...
}

Is it due to the fact that C++ is not able to catch arithmetic exception ? Or is there a way to do that ?

Edit :
I try to catch the SIGNALFPE in my Fortran Function when I divide by zero (using SIGNALQQ(SIG$FPE, MY_HANDLER)) but it doesn't work. Maybe due to the fact that the main function is not a Fortran Function but a C++ one ?

Another way of work :

My aim is to be able to have the same behavior as the ERRSET function used in VAX (unfortunately not still supported for Intel Fortran in Linux)

If an error occur during my Fortran Code call from a C++ function. I want my Fortran treatment to continu but store somewhere the information of the occured error (Like ERRSET do).

Is there any way to have this behavior with Intel Fortran for Linux ?

Thanks.

No one has an idea ?

Is there a simple way to say : If my an arithmetic error occurs I continu the program (I know how to do this) but trace in a file the error ? I assume that if an unhandle error occures, my Fortran Code and my main C++ Program crash (unless if someone know how to handle a Fortran error in C++).

Have you looked at using IEEE_FLAGS instead of IEEE_HANDLER?

I dont know anything about the ERRSET but from your desired behavior it seems you want information about the occurrence of a specific exception but not take any specific action. IEEE_FLAGS appears to provide that.

Thanks for you answer.

Ok for setting the different flag depending on which type of exception. But if (for example) a divide by zero occures, I can decide to continu my treatment (using the right Flag) but how can I specify that I want to have a trace of this error (in mean in a file for example), all the error that occur during the treatment and information about the routine and the line where this error occur ?

Use TRACEBACKQQ and compile with g and traceback to ensure the trace is symbolized. The trace is printed to stderr.

I've already use TRACEBACKQQ, but I have to call it where I know my program will fail. Here the need is I have for example a routine with 100 line of code, I don't know where my program will fail. So I want, if one or more errors occur during the call of this routine, to store the errors information in stderr (or a file, I don't mind).

Sorry. I am not having any success getting control back from the interrupt handler for the various methods available. I will continue investigating and post again with any new information.

I'm also interested in this question; although, I'm interested in catching any type of exception, not just floating point exceptions (e.g., I'd also like to catch array index out of bounds exceptions, etc.).

What happens when you change your C++ code to the following?

try

{

printf("Before"
);

MyFortranFunction();

printf("After"
);

}

catch (...) // handle any exception

{

printf ("Exception catched
");

}

You gave the printout when the catch block was handling specifically "const std::exception&" exceptions, but about when this code handles an arbitrary type? A subsequent post of yours uses "..." for the "catch" block argument, but that post doesn't show what your code does in the case that an arbitrary exception is caught. Does it print a message?

Regards.
Greg

Leave a Comment

Please sign in to add a comment. Not a member? Join today