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

Stack corruption on return

Don_D_
New Contributor I
596 Views

My Fortran code enters a subroutine SYNO.  That calls a C++ routine that creates some mapped files via CreateFileMapping.  That routine calls another Fortran sub called SYNORUN and passes the addresses of three mapped files.  SYNORUN does lots of calculations and spawns multiple processes, all of which write to the same mapped file addresses.  When the C++ code returns, SYNO then returns.  So far, so good.  This works in debug mode.

It also works in release mode, but only if I turn optimization off.  If I turn it on, I get weird behavior, as follows:

The call to SYNO works as before.  And if I later call SYNO again, it works -- but only if I call it from the same place as before.  But if I call it from a different subroutine, then when the C++ routine returns, the call stack collapses and then only contains the current address in SYNO.  Then when SYNO tries to return, there is no return address and it crashes.

Another data point:  If I do not put a SAVE directive at the top of SYNO, then the same crash happens even in debug mode.

Any ideas what is causing this?  Is there any way to monitor the stack to see where it gets corrupted?  This is weird.  The folks on a C++ forum assure me that the mapped files do not affect the stack.  So what's going on?

0 Kudos
1 Solution
Don_D_
New Contributor I
596 Views

After much trial and error, I narrowed down the problem.  I can compile the release version with optimization turned on for the Fortran code, but with optimization turned off for the C++ part.  Then everything works.

Since the C++ is used only for the GUI where speed is not an issue, this is a satisfactory solution.  The actual cause is still a mystery, but it seems to point to the C++ not managing the call stack properly when optimized.  At this point, I don't care about those details.  What I have works.

View solution in original post

0 Kudos
3 Replies
jimdempseyatthecove
Honored Contributor III
596 Views

It is difficult to prognosticate the problem without seeing the complete code. Unfortunately it is often the case that this code cannot be shared, or it is to complicated to properly asses in a forum such as this. This said, one thing gives a possible hint:

>>The call to SYNO works as before.  And if I later call SYNO again, it works -- but only if I call it from the same place as before...
>>  If I do not put a SAVE directive at the top of SYNO, then the same crash happens even in debug mode.

What this indicated to my is that one of the routines in the CALL stack is passing the address of a local (stack) variable for use as a reference on subsequent calls. IOW, when all calls are made from the same location .AND. same stack level, IOW even though you may have popped up a few levels then then called down the same few levels, then the variables passed by reference thus happen by chance to be located at the same address. Then when called elsewhere .OR. from same source and line number but different call stack level, the location of the (saved) reference differs, and thus when used, disturb your program.

I suggest you follow all variables passed from SYNO into your next levels and determine if any code assumes the references are persistent for any subsequent calls. One such situation that can byte you is if in an early level you have a once only test, that sets up a buffer (that uses a referenced buffer on the first call), does some lengthy setup code, then continues through code that assumes those buffers do not change.

Jim Dempsey

0 Kudos
Don_D_
New Contributor I
597 Views

After much trial and error, I narrowed down the problem.  I can compile the release version with optimization turned on for the Fortran code, but with optimization turned off for the C++ part.  Then everything works.

Since the C++ is used only for the GUI where speed is not an issue, this is a satisfactory solution.  The actual cause is still a mystery, but it seems to point to the C++ not managing the call stack properly when optimized.  At this point, I don't care about those details.  What I have works.

0 Kudos
jimdempseyatthecove
Honored Contributor III
596 Views

Don,

I caution you not to assume that because the crash went away that the problem has been solved. In particular, because you stated that the symptom was affected by the SAVE statement.

It is not unusual, as an example, for an uninitialized variable (reference or pointer to buffer) to be observed with the same uninitialized value on each call. And, due to the fortunate or unfortunate placement of code and data, the problem is either hidden or exposed.

Jim Dempsey

0 Kudos
Reply