- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
have a trivial test program that implements one function, INV, which just computes 1/x. Passing 0 for the argument x triggers a zero-division error. When I compile it with ifort (version 2021.3.0), using the flags "/fpe-all:0 /traceback /fp:strict /debug" and run it, I get a traceback like this:
forrtl: error (73): floating divide by zero
Image PC Routine Line Source
ifort-tst.exe 00007FF7EB0411F0 F_mp_INV 9 f.f
ifort-tst.exe 00007FF7EB0410A2 MAIN__ 8 tst.f
In my real application, we call Fortran code from a Python process, using f2py. With a bit of tinkering (had to define macros UPPERCASE_FORTRAN and NO_APPEND_FORTRAN) I was able to compile the same code as a Python module. When I run it from Python, the zero-division causes the program to quit but does not produce the backtrace. If I don't set "/fpe-all:0" the module just returns a NaN instead of aborting, so I know the FPE compiler flags are in effect. I want the program to abort on floating-point exceptions, but I want to see the same type of backtrace that is produced when I run the code as a stand-alone executable.
I suspect that some needed signal handler is not getting registered - with GNU Fortran it's necessary to call a few library initialization functions to make FPE handling work but I was not able to find the equivalent in the Intel Fortran documentation.
|
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
My understanding of how this works is that the traceback is generated by a C++ wrapper around a Fortran main program, and if there is no Fortran (or Intel C++) main, then you don't get tracebacks. You CAN call TRACEBACKQQ at any point to get a traceback, and you might investigate whether adding a call to SIGNALQQ, to register your own handler, gives you a place from which to call TRACEBACKQQ.
Your use of /fpe-all is correct in that without this, the setting of FP exception handling is done in the main program only. /fpe-all adds the call to do this in every procedure. But it doesn't help with traceback.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks Steve, this is exactly the kind of info I was looking for.
It seems like a signal handler needs to be set up to trap SIG$FPE.
I followed your suggestion of calling TRACEBACKQQ, this works as expected when I call if from a Fortran main program, but not when I compile the code as a library and call it from Python. It does cause the program to exit, but the traceback just isn't printed. If we can figure out why that's happening, I'll be all set.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
On Linux, calling TRACEBACKQQ from an f2py-generated module works - it prints a traceback and aborts. On Windows, it aborts without printing a traceback.
In neither case do I get a traceback on FPE, even if I call SIGNALQQ(SIG$FPE, TRACEBACK) where TRACEBACK is a function that calls TRACEBACKQQ. (The wrapper needed to match expected signature for SIGNALQQ).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I'm afraid my understanding of this part of things is very superficial - not sure I have more I can add. I think TRACEBACKQQ prints to stderr - maybe it can't open that? I suggest you look more carefully at the documentation of TRACEBACKQQ - it has a bunch of stuff about exception pointers.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
One small step forward, TRACEBACKQQ noiw works from f2py wrapper on Windows if I include the line
USE IFCORE
which I had been missing (the code compiles without this, just doesn't print a traceback on Windows). Still haven't gotten this to work from the FPE handler, though.
-- Chuck
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
According to this stackoverflow post ,
"TRACEBACKQQ has optional arguments. It thus requires an interface to be in scope at the calling point. This is achieved by using the IFCORE module"
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page