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

Run-Time Check Failure #2

Adrian_F_1
Beginner
1,097 Views

I am getting the following message when I leave a particular subroutine, at the end statement:

Run-Time Check Failure #2 - Stack around the variable '.T209_' was corrupted.

By trial and error I have traced it to the calling of another subroutine, "A", 4 levels below. If I comment out the call to this subroutine "A" the error goes away.  However if I still call "A" but remove all the code inside it, I get the error. So it looks like a argument list issue.  However all the arguments match fine.  Most of the arguments are structures from USE'd modules which both the caller and callee USE.

How do I debug this further?

0 Kudos
10 Replies
Arjen_Markus
Honored Contributor I
1,097 Views

It may be a matter of the interface being visible to the compiler or not. Does routine A itself come from a module?


 

0 Kudos
andrew_4619
Honored Contributor III
1,097 Views

Are they compiled with the same options for calling conventions? Arg mismatch  is a prime suspect, maybe it looks like a match but there is a subtle error. Post some bits of code showing the call  and caller and callee declarations for other to have  a look at maybe......

0 Kudos
Adrian_F_1
Beginner
1,097 Views

Here is a code snippet:

Caller:

      subroutine pd_ext(brdata,ip,op,lo,d1,d2,err)

      use genexp_env
      use pipe_env
      use intpipe_env
      use mathparam_env
      implicit none
!
! DECLARE AND DESCRIBE ARGUMENTS HERE
....

! DECLARE LOCAL VARIABLES HERE
      type (FlowStruct)                 :: FlowS
      type (PHTStruct)                  :: PHT
      type (ErrorStruct)                :: Err
      type (EquipmentParametersIntPipe) :: EqParams
      type (MiscIntPipe)                :: Misc
      type (StdCondStruct)              :: StdCond

!-----call pipe routine
goto 999     ! get stack crash 3 levels up if this is commented out
      call IPW(FlowS, PHT, Misc, EqParams, StdCond, Res, DerRes, Err)

  999 continue

      return
      end



IPW:

      subroutine IPW(Flow, PHT, Misc, EqParams, StdCond, Res, DerRes, Err)
      use genexp_env
      use pvt_env
      use pipe_env
      use intpipe_env
      implicit none

! DECLARE AND DESCRIBE INPUT ARGUMENTS HERE
      type (FlowStruct),      intent(in)  :: Flow
      type (MiscIntPipe),     intent(in)  :: Misc
      type (StdCondStruct),   intent(in)  :: StdCond

! DECLARE AND DESCRIBE OUTPUT ARGUMENTS HERE
      type (PHTStruct),                               intent(inout)  :: PHT
      type (EquipmentParametersIntPipe),              intent(inout)  :: EqParams
      type (ErrorStruct),                             intent(out)    :: Err
      double precision, dimension(2),                 intent(out)    :: Res
      double precision, dimension(2,Flow%iNCompts+4), intent(out)    :: DerRes

      return
      end

 

0 Kudos
Arjen_Markus
Honored Contributor I
1,097 Views

By the looks of these fragments, the routine PD_EXT and IPW are not contained in a module, otherwise you could not have used an "END" statement. So the question is: can the compiler see the interface of IPW? Since you use all manner of derived types as well as arrays, I would play at safe and make sure IPW is contained in a module. And is the value of Flow%INCompts set to a reasonable value?

Regards,

Arjen

A

0 Kudos
Adrian_F_1
Beginner
1,097 Views

arjenmarkus wrote:

By the looks of these fragments, the routine PD_EXT and IPW are not contained in a module, otherwise you could not have used an "END" statement. So the question is: can the compiler see the interface of IPW? Since you use all manner of derived types as well as arrays, I would play at safe and make sure IPW is contained in a module. And is the value of Flow%INCompts set to a reasonable value?

Regards,

Arjen

A

No, both routines are in separate f90 files and linked into a library and are not modules.  Yes Flow%INCompts is set to 8 so the total array size is 12.

I just now put IPW in a module and got the caller to USE it, but I still get the same stack problem.

Adrian

0 Kudos
andrew_4619
Honored Contributor III
1,097 Views

I could not see anything that looks like an obvious problem. There can be issues issues with intent(out) for derived types in that any components that are not assigned in the subroutine could be undefined on exit. All components should be assigned..

Do you have run time checks for array bounds? I an thinking wrt double precisiondimension(2,Flow%iNCompts+4), intent(out)    :: DerRes. 

Out on interest does the problem go away with intent(out) changed to (inout)? 

0 Kudos
Adrian_F_1
Beginner
1,097 Views

Found my problem.  It was an argument mismatch 2 levels up.  I thought in the old days the linker would flag argument mismatch errors.  In this case 7 as opposed to 8 arguments.  Pity that useful functionality seems to have been lost unless there is a special flag these days.

0 Kudos
IanH
Honored Contributor II
1,097 Views

Edit: you found it in the meantime, so the following may not be so pertinent, but just in case in comes handy for next time...

Be mindful that the presence of the call to the procedure that you think is problematic may just result in the stack being arranged such that a problem created elsewhere becomes observable. 

Writing beyond either end of an array that is being stored on the stack would be a common cause of this sort of error.  It depends on compile options, but often temporary arrays created as part of argument association live on the stack.  Temporary arrays may be created for actual arguments that are deferred or assumed shape that are then associated with explicit shape arguments - `Res` and DerRes` being such explicit shape arguments. 

The following may be a little nebulous, because I don't have a nice example of stack corruption to use to generate specific steps, but within a debugger (say the Visual Studio debugger, you should be able to get some idea of the specific stack location (memory address - perhaps relative to the stack base or to the stack pointer value when the highest level procedure begins executing) where corruption has been detected from the error message and the execution context active when the message is issued.  Before your chain of procedures executes you can then set a breakpoint to stop execution when your program attempts to write to that address - the statement being executed at the time of that breakpoint may then help narrow down the problem.  Or it might just distract you.

Edit to further note that with most calling conventions in use with Fortran the linker has absolutely no idea (or at best, very little idea) of the arguments being passed.  Separate to any compiler/linker diagnostic magic (/warn:interfaces - if you are not already using that), the modern language provides facilities that practically enable that checking at compile time - their use is strongly recommended.
 

 

0 Kudos
Arjen_Markus
Honored Contributor I
1,097 Views

In the old days some decoration was added to the name of the symbol which involved the number of bytes that had to be passed. A consequence of the "stdcall" convention. But that did not prevent you from interchanging integers and double precision reals or any other combination.

Nowadays we can rely on the interfaces inherent in the use of modules (one reason I mentioned them a number of times ;)) and the Intel Fortran compiler generates - by default, I think - modules with the interface definitions for routines that are not contained in a module or another routine. The option in Visual Studio is, as far as I can tell: "Check routine interfaces" (warn:interfaces), but I am not entirely sure. (The compiler generates these "under water" modules when compiling the source code, so that code must be part of the solution/project, of course)

 

0 Kudos
andrew_4619
Honored Contributor III
1,097 Views

If the subroutine with mismatched parameters was in a module the compiler would have been able to check and flag that error. Failing that the warn interfaces option would also find that error.

 

 

0 Kudos
Reply