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

!DEC$ ATTRIBUTES STDCALL, REFERENCE problem

jarvusluntatintel
714 Views

I'm trying to add !DEC$ ATTRIBUTES STDCALL, REFERENCE to about a dozen external calls and it is causing a memory leak type behavior (your program has encountered an error, do you want to send Microsoft...).

The program links to a third party, fortran static library that expects STDCALL, REFERENCE. I've used this library successfully for years with the calling convention of my program set to STDCALL, REFERENCE. However, for future changes, I want to change the calling convention to "default" and write interface statements for the dozen or so calls that I make to the static library. When I tried this, the debug version [appeared] to run correctly but the release version would crash. I changed the calling convention back to STDCALL, REFERENCE, commented out all of the interface blocks (everything worked) and then starting adding the interface blocks back in one at a time. Some appeared to work and some did not. For instance:


SUBROUTINE HEC_DATJUL (DATE, J, IERR)

INTERFACE

SUBROUTINE DATJUL_ (DATE, J, IERR)

!DEC$ ATTRIBUTES STDCALL, REFERENCE ::DATJUL_

INTEGER J, IERR

CHARACTER(*) DATE

END SUBROUTINE DATJUL_

END INTERFACE

INTEGER J, IERR

CHARACTER(*) DATE

CALL DATJUL_ (DATE, J, IERR)

RETURN

END

The release version crashes with the above code, but it will run if I comment out the interface/end interface block. DATJUL_ is the call to the library routine.

Curiously, when I added in some write statements around the call:


write (123,*) 'HEC_DATJUL 1'

CALL DATJUL_ (DATE, J, IERR)

write (123,*) 'HEC_DATJUL 2'

it suddenly started running in release mode. Even more curious, when I comment this interface block out and try a different, problamatic call, it also would work in release mode, but only with the write statements".

FUNCTION HEC_XREAL (STRING, I, L, IERR)

INTERFACE
FUNCTION XREAL_ (STRING, I, L, IERR)
!DEC$ ATTRIBUTES STDCALL, REFERENCE ::XREAL_
REAL XREAL_
INTEGER I, L, IERR
CHARACTER(*) STRING
END FUNCTION XREAL_
END INTERFACE
REAL HEC_XREAL
INTEGER I, L, IERR
CHARACTER(*) STRING
write (123,*) 'HEC_XREAL 1'
HEC_XREAL = XREAL_ (STRING, I, L, IERR)
write (123,*) 'HEC_XREAL 2'
RETURN
END

The above will run but will crash if the write statements are commented out.

Am I missing something about Interface blocks or the !DEC$ attributes? This program has a wide distribution. If there is a memory leak on my end, it is very well hidden when I don't use the interface blocks, but happening all of the time when I add them in. Also, I believe the third party library is a fortran wrapper around c++ code, but I've never had a problem with it before. My program and the library are using Intel 9.1.

Thanks for any help.

0 Kudos
2 Replies
thomas_boehme
New Contributor II
714 Views
Does the old library expectCompaq Fortranstyle interfaces?
If yes, then you need to add MIXED_STR_LEN_ARG to your DEC$ line. Intel Fortran adds the lengths arguments to the end, while CVF didput it directly after the string argument.
If that's not the cause of your problem, is there any commonality between the subroutine/functions that work well and those that don't? Are the one that don't work using strings or variable size arrays, etc.?
regards,
Thomas

0 Kudos
jarvusluntatintel
714 Views
I don't believe the library expects CVF interface. If I take out the interface (and my global setting is Standard call Reference), everything works. I wouldn't expect this to be the case if the library required CVF settings (and I have used this library for years). Most of the calls have one or two variable length strings, and a couple of integers. Some have reals and/or integer/real arrays, but no variable length arrays. I don't see any commonality between those that work and those that don't. But there appears to be some randomness since I can make at least some of those that "don't work" start working by adding write statements. Given that the debug version has always worked (so far) it would appear to be a memory leak on my end or I am doing something that the compiler does not like. But I can take a version of the code that has been released and used by thousands of end-users (with no reports of this memory bug), add the interface block to one subroutine, and it starts crashing in release for different data sets. The interface block should, if I'm doing things correctly, be redundant since the external call is set to Standard Call Reference anyway.
So given that the interface block shouldn't be changing how the call is made to an external library, and that the problem only happens with the release version, if anyone has any insight on where I should direct my search for a memory leak, it would be greatly appreciated.

0 Kudos
Reply