I need a better understanding of polyglot signal raising and handling.
I'm using fortran from the JVM on windows. I'm reasonably familiar with the signal handling facilities of the JVM, but they do not interact nicely with my current fortran-built binaries.
The generated fortran code sometimes seems to fire windows error messages, and sometimes kills our application (I believe with SIG_ABRT).
What kinds of floating-point error processing facilities do I have? Specifically I'm just not sure which compiler is generating which code and where it is run and how a thread plays into it.
I believe what is happening is:
1. java code JNA's into fortran routine. JNA uses C++ style structured exception handling (SEH). ourwrapper.exe -> jvm.dll -> jnidispach.dll -> ourfortran.dll. I don't understand how linkers treat SEH code.
2. our fortran code does something dumb, for us this is often a floating-point error (FPE), but may be other integer or memory mistakes mistakes.
3. SIG_FPE is raised.
4. SIG_FPE is handled by a fortran generated handler, which eventually results in EndProcess()
Given that I am talking about errors (not any kind of unhappy path), and it would be irresponsable to give control back to any portion of fortran because it isn't written with any concept of exceptions. What I would like is to use SEH or a long-jump to hit the surrounding JNA provided exception handler, to be raised in the JVM as some kind of error.
Indeed this seems to already happen with SIG_SEGV as a JVM's `IllegalMemoryAccessError`. I want this same behaviour for all types of errors. The problem is I'm just not sure whose raising and whose processing which signals.
1. are signal handlers localized to DLL's in win32?
2. is fortran overwriting the JVM's own signal processing for SIG_ABRT and/or SIG_FPE?
3. does fortran use some other facilities than signals to process
4. how can I enforce strict IEEE754 just use NaN style FPE?
5. Is there some kind of telemetry I can attach to a process to let me do things like get a trace of which signals are raised and which handlers (from which DLL's) are getting called?
Thanks for any help,
This is an updated version of the 15 year old forum post: https://software.intel.com/en-us/forums/intel-fortran-compiler/topic/272052
the JVM has a non-published API to handle signals: http://esus.com/catching-specific-signalinterrupt-java/, the start of which is in native code here: https://github.com/openjdk/jdk/blob/6bab0f539fba8fb441697846347597b4a0ade428/src/java.base/share/native/libjava/Signal.c
I haven't found much mention of signals from fortran's page on error handling here: https://software.intel.com/en-us/fortran-compiler-developer-guide-and-reference-advanced-exception-and-termination-handling
Intel Fortran doesn't have intrinsic support for signals. The language provides mechanisms in the IEEE intrinsic modules for performing operations and detecting whether an error was raised.
To this, you would have to add a C++ -> C wrapper that saves the stack pointer in a static location, calls the Fortran subroutine/function of interest, if no error, clears the saved stack pointer. If error occurs in Fortran, your Fortran error handler takes any corrective action you design, or if unhandled by your code, your Fortran error handler makes a call to your C error handler (passing an error code), which then performs the stack restore (provided saved stack pointer not NULL), returns to the C++ wrapper, which tests for error and throws error if error indicated.
If you do implement this in a general way, please post your handlers here for future reference.
I should have mentioned that the information in the link provided in #4 is somewhat incomplete. In the FPE_SETUP handler (document doesn't say this but I assume) you will need to add one handler for each signal or add one handler for "all", or "common"...
... also, prior to doing so, you should perform action 'get' to obtain the INTEGER(C_PTR) of the prior handler if any, and add code to restore it on both success and fail returns.
Expect potential quirks should your Fortran call an additional library that does the same or expects default handlers to be in place.