- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
this code fragment
DO I=1,100000
write(line,*)' daj i= ',i
write(*,*)line
iret = cwrstat(line)
DO j=1,100000
a=a+1.0 + i/1000.0
enddo
if( i.eq.1 .or. i.eq.100)write(*,*)' daj ',a
enddo
Generates this error:
forrtl: severe (8): internal consistency check failure, file for_desc_item.c, line 590
CWRSTAT is in a DLL.
Any help as to what causes this?
Link Copied
7 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Insufficient information. The error is equivalent to an internal compiler error, but it is most often caused by the program "stomping on memory" somewhere. One can't analyze this based on a code fragment.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I'm using 11.1.065 on a 32 bit machine. The dll is made for 32 bits. You should probably take out the pause statement too.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Even though there are dependent DLLs missing, I can see the problem. The DLL routines are evidently built with the STDCALL interface, which is why their names end in @4, @8, etc. You declare interfaces to these routines with blocks such as this:
What I suggest you use instead is simply:
!DEC$ ATTRIBUTES STDCALL, REFERENCE, DLLIMPORT :: CWRSTAT
with similar declarations of the other routines. The compiler will automatically add the appropriate "decoration" and will know that the called routine pops the stack.
What I find a bit puzzling is that some of the DLL routines do not have the @n suffix, though you're not calling those. It's unusual to have a mix in the same DLL. You should read this DLL's documentation carefully to make sure that you are using the right calling and argument passing conventions.
[fortran]!DEC$ IF DEFINED(_X86_)Note that you use ALIAS to explicitly add the @8 to the name, but you don't also specify STDCALL. A big hint - if you ever think you need to add the @n to an ALIAS, you're almost certainly making a mistake. It would have been ok if you compiled your source with /iface:cvf or /iface:stdref, but you didn't. The result is that every time you call CWRSTAT, you corrupt the stack by 8 bytes since the called routine pops 8 bytes from the stack as does the caller.
!DEC$ ATTRIBUTES DLLIMPORT,ALIAS:'_cwrstat@8' :: CWRSTAT
!DEC$ ELSE
!DEC$ ATTRIBUTES DLLIMPORT,ALIAS:'cwrstat' :: CWRSTAT
!DEC$ ENDIF[/fortran]
What I suggest you use instead is simply:
!DEC$ ATTRIBUTES STDCALL, REFERENCE, DLLIMPORT :: CWRSTAT
with similar declarations of the other routines. The compiler will automatically add the appropriate "decoration" and will know that the called routine pops the stack.
What I find a bit puzzling is that some of the DLL routines do not have the @n suffix, though you're not calling those. It's unusual to have a mix in the same DLL. You should read this DLL's documentation carefully to make sure that you are using the right calling and argument passing conventions.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It isn't that straightforward. The function is defined with
extern "C" {
__declspec(dllexport) int __stdcall cwrstat( char *message, int len);
}
Which I think explains the name mangling and why the existing code links and runs. But I'm not sure it explains the memory overwrite.
The suggested changes to the declarations didn't work.
extern "C" {
__declspec(dllexport) int __stdcall cwrstat( char *message, int len);
}
Which I think explains the name mangling and why the existing code links and runs. But I'm not sure it explains the memory overwrite.
The suggested changes to the declarations didn't work.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The function being declared that way supports my comment that you're using the wrong calling convention. The C routine wants STDCALL (that's what the __stdcall does) and therefore the caller has to know to use STDCALL conventions. Intel Fortran uses the C convention by default, so you have to use ATTRIBUTES STDCALL to tell it otherwise. This will cause the name to be downcased and the proper "decoration" added.
It may be that the stack corruption was not the issue, but it would surely bite you eventually.
The DLL has at least one other non-standard DLL it depends on that you didn't include, so I can't try it myself.
It may be that the stack corruption was not the issue, but it would surely bite you eventually.
The DLL has at least one other non-standard DLL it depends on that you didn't include, so I can't try it myself.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I also need lsapiw32.dll. Please also attach your corrected Fortran source so I can be sure you made the appropriate changes.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Ah ha! The key was to add the interface statement and not just change the attributes line. I hadn't tried that , but now see why it is needed. Thanks. Funny thing is that this DLL has been being used for about 12 years with the same 2 errors in it. But they seem to have canceled out and it has worked fine for all that time. Thanks for helping to fix this.

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page