- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It may be a matter of the interface being visible to the compiler or not. Does routine A itself come from a module?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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......
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
precision
,
dimension
(2,Flow%iNCompts+4),
intent
(
out
) :: DerRes.
Out on interest does the problem go away with intent(out) changed to (inout)?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
![](/skins/images/2E08A100FB92911314A240D1EAFB2828/responsive_peak/images/icon_anonymous_message.png)
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page