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

Recursive I/O operation error inside error handler

ereisch
New Contributor II
460 Views
Is there a way to "terminate" an in-progress WRITE operation to a device? As noted in the summary, I have a program which is generating an array bounds error (#408) when building output for a WRITE statement. The RTL dutifully calls my error handler that I've registered with ESTABLISHQQ with the subscript array bounds message. My error handler does its thing (begins an orderly shutdown, never returning to the calling function), but as part of that shutdown it wants to print out the error message returned to it from the RTL. Unfortunately, since it looks as though the RTL doesn't "flush" (or complete? terminate?) the WRITE statement prior to calling the error handler, I get a recursive I/O operation error (#40) when I try printing the error message to LU #6. Is there a way I can forcefully "terminate" the hold the faulting WRITE statement has on the I/O device (STDOUT) from my error handler, so I can send the error message text to it? Unfortunately, I appear to have not coded my error handler to deal with this condition gracefully, so when the attempted write to STDOUT generates another RTL exception, it calls the error handler again, which then tries printing to STDOUT again, ad infinitium, until my stack overflows. While I can probably trap this case by immediately unregistering my error handler with the RTL upon entering (or setting a variable state to detect and prevent recursion), I would still prefer to be able to issue the error message to the terminal. Thanks in advance. EDIT: Using ifort 15.0.2
0 Kudos
6 Replies
Steve_Lionel
Honored Contributor III
460 Views

No, but you could open a separate unit to stderr and write your info there. Unit 0 is preconnected to stderr.

0 Kudos
ereisch
New Contributor II
460 Views
Can I request a "feature upgrade" to the RTL that terminates all pending WRITE operations if an ESTABLISHQQ routine is called with the CONTINUABLE flag set to .FALSE.? It seems the RTL does this already on its own if you have not registered an ESTABLISHQQ routine, since it is able to write its own error message to UNIT=6 in these cases. I understand wanting to keep these locks in-place if the calling routine is allowed to continue, but in this specific case, since the RTL is setting CONTINUABLE to .FALSE., the library is presumably never expecting the error handler to return, so maintaining the lock on the output device seems unnecessary. Thanks again
0 Kudos
Steve_Lionel
Honored Contributor III
460 Views

No, the RTL writes these messages to stderr,. not any particular unit. There is a lot to go through to "unwind" a current operation, and typically with errors that may not be possible or might lead to other errors. Writing to unit 0 or a different unit is quite simple.

0 Kudos
ereisch
New Contributor II
460 Views
Ok, I'll have to find another workaround. It is certainly easy to write to unit 0, yes, but in our case, the program often reopens unit 6 to direct output to a file, so if we sent the error text to unit 0, it would become disjoint with the main program output. Thanks
0 Kudos
jimdempseyatthecove
Honored Contributor III
460 Views

Would it be out of the question for your application to start an additional process (either before or in your error handler) and send the message to the additional process. Due to the nature of your error handler itself, causing an error, I'd suggest that after a few recursive errors that you hang the error process. Or....

On the first occurrence of the recursive error either hang or launch the debugger as the additional process and then attach back to your app with the error. You can then force a break into the failing app and then use the debugger to explore what happened.

Jim Dempsey

0 Kudos
jimdempseyatthecove
Honored Contributor III
460 Views

>>so if we sent the error text to unit 0, it would become disjoint with the main program output.

Timestamp your outputs, then merge. You would still have the issue of what was not flushed to the main output unit.

Jim Dempsey

0 Kudos
Reply