- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
When we compile the Fortran code below, we get this error in Visual Studio:
Exception thrown at 0x4B426F3 (kbcunitop.dll) in Petro-SIM.exe: 0xC000005: Access violation reading location 0xFFFFFFFF
I apologize for not being able to include a full project and all the files, but the error is very reproducible using only a small snippet of code, and centers around this snippet of code:
integer, parameter :: UNINT = -32767
DO 20 I = 1 , LMIDEX MINDEX (I) = UNINT 20 CONTINUE
The rest is not really relevant.
SUBROUTINE BDINDX
INCLUDE 'SYS_UNDEFINED.INC' INCLUDE 'SYS_MINDEXSIZES.INC' INCLUDE 'INDEXS.COM' INCLUDE 'SINDEX_CACHES.COM' * * INTRINSIC MIN * INTEGER I,INT1,TYPEC,IOS CHARACTER CHAR2*20 DOUBLE PRECISION REAL1 * * ------------------------------------------------------------------------------ * LMIDEX = MMIDEX CALL GTCFGK ('LMIDEX',CHAR2,INT1,REAL1,TYPEC,IOS) IF ( IOS.EQ.0 .AND. TYPEC.EQ.2 ) THEN LMIDEX = MIN(INT1,LMIDEX) ENDIF DO 20 I = 1 , LMIDEX MINDEX (I) = UNINT 20 CONTINUE * MINDEX(1) = 0 MINDEX(3) = 0 MINDEX(4) = SIZTOP + 1 MINDEX(7) = 0 MINDEX(8) = 0
Indexs.com has:
INTEGER MMIDEX,MSIDEX,LSIDEX,LYMSTK,LMIDEX PARAMETER (MMIDEX=120000,MSIDEX=6000,LYMSTK=10) INTEGER MINDEX(MMIDEX),SINDEX(MSIDEX),PMODEL,PSCLST,MOFFST, & & YMSTCK(3,LYMSTK),TOPYMS COMMON /INDEX1/ MINDEX,PMODEL,PSCLST,MOFFST,YMSTCK,TOPYMS
The compile options are:
/fp:source /Ox /W1 /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /c /nologo /warn:nofileopt /align:rec1byte /iface:mixed_str_len_arg /include:"c:\PROGRA~2\INTELS~1\PARALL~1.041\COMPIL~1\windows\compiler\include\ia32" /include:"c:\PROGRA~2\INTELS~1\PARALL~1.041\COMPIL~1\windows\compiler\include" /Fomobj32p\kbcunitop\ /module:mobj32p\kbcunitop /include:..\FCC-SIM /include:..\Petrofine\includes /include: /compile_only /dll /threads /assume:byterecl /libs:dll /define:KBCIFORTRAN
The compiler is:
Intel(R) Visual Fortran Compiler for applications running on IA-32, Version 16.0.0.110 Build 20150815
Copyright (C) 1985-2015 Intel Corporation. All rights reserved.
The assembly generated is:
_BDINDX:
04B42680 push ebp 04B42681 mov ebp,esp 04B42683 and esp,0FFFFFFF0h 04B42686 push esi 04B42687 push edi 04B42688 push ebx 04B42689 sub esp,14h 04B4268C mov dword ptr ds:[53122E0h],1D4C0h 04B42696 lea esi,[esp+10h] 04B4269A lea ebx,[esp+0Ch] 04B4269E lea edi,[esp+8] 04B426A2 lea eax,[esp] 04B426A5 push esi 04B426A6 push ebx 04B426A7 push eax 04B426A8 push edi 04B426A9 push 14h 04B426AB push 58E4CE0h 04B426B0 push 6 04B426B2 push 4F08A50h 04B426B7 call _GTCFGK (04BF3300h) 04B426BC add esp,20h 04B426BF cmp dword ptr [esp+10h],0 04B426C4 jne _BDINDX+51h (04B426D1h) 04B426C6 cmp dword ptr [esp+0Ch],2 04B426CB je _BDINDX+263h (04B428E3h) 04B426D1 mov edx,dword ptr ds:[53122E0h] 04B426D7 test edx,edx 04B426D9 jle _BDINDX+0BCh (04B4273Ch) 04B426DB cmp edx,10h 04B426DE jl _BDINDX+29Eh (04B4291Eh) 04B426E4 mov eax,edx 04B426E6 xor ecx,ecx 04B426E8 movdqa xmm0,xmmword ptr ds:[4F08A40h] 04B426F0 and eax,0FFFFFFF0h 04B426F3 movdqa xmmword ptr [ecx*4+5297198h],xmm0 CRASH LINE 04B426FC movdqa xmmword ptr [ecx*4+52971A8h],xmm0 04B42705 movdqa xmmword ptr [ecx*4+52971B8h],xmm0 04B4270E movdqa xmmword ptr [ecx*4+52971C8h],xmm0 04B42717 add ecx,10h 04B4271A cmp ecx,eax 04B4271C jb _BDINDX+73h (04B426F3h) 04B4271E lea ecx,[eax+1] 04B42721 cmp edx,ecx 04B42723 jb _BDINDX+0BCh (04B4273Ch) 04B42725 sub edx,eax 04B42727 xor ecx,ecx 04B42729 shl eax,2 04B4272C mov dword ptr [eax+ecx*4+5297198h],0FFFF8001h 04B42737 inc ecx 04B42738 cmp ecx,edx 04B4273A jb _BDINDX+0ACh (04B4272Ch) 04B4273C push esi 04B4273D push ebx 04B4273E xor edx,edx 04B42740 lea eax,[esp+8] 04B42744 push eax 04B42745 push edi 04B42746 push 14h 04B42748 push 58E4CE0h
We can work around it by creating a method that gets called that just assigns the desired value to the entire array in one go. That method CANNOT be in the same file, otherwise the compiler optimises it out and it crashes again. This crash did not manifest in earlier versions of Intel Fortran and does not manifest if compiled with the Od option.
We do have many registered Intel Fortran users, I tried to log this issue with support, but I had no luck with that web site.
Lionel, maybe you can pass this to them, please?
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Sorry, I can't do anything with this without a complete test case. I don't even see a declaration of MINDEX.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The scary thing is, I have set up a Visual Studio project, same Fortran version, same compile options, this file and the include files only. Never crashes or generates the assembly shown. I guess it shall remain a mystery.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Steve,
04B426E4 mov eax,edx 04B426E6 xor ecx,ecx 04B426E8 movdqa xmm0,xmmword ptr ds:[4F08A40h] 04B426F0 and eax,0FFFFFFF0h 04B426F3 movdqa xmmword ptr [ecx*4+5297198h],xmm0 CRASH LINE 04B426FC movdqa xmmword ptr [ecx*4+52971A8h],xmm0 04B42705 movdqa xmmword ptr [ecx*4+52971B8h],xmm0 04B4270E movdqa xmmword ptr [ecx*4+52971C8h],xmm0 04B42717 add ecx,10h 04B4271A cmp ecx,eax 04B4271C jb _BDINDX+73h (04B426F3h)
The base of the array is at 0x5297198, this is at an odd number of multiple of 8 address. movdqa requires a multiple of 16 byte address. (ecx walks from 0, stride 10). There should have been a general protection fault not a fault reading 0xFFFFFFFF.
benifck,
Did you make any declaration as to if MINDEX were aligned? Can you provide your declaration of MINDEX including any !DEC$ decorations.
The binary code could exhibit this behavior when your COMMON or module based array did .NOT. have an alignment declaration, .AND. your subroutine has a directive (possibly implied by option) that specifies the array is aligned (and the array by chance did not fall on an aligned address).
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The declaration of MINDEX is given in the third code snippet above:
INTEGER MMIDEX,MSIDEX,LSIDEX,LYMSTK,LMIDEX PARAMETER (MMIDEX=120000,MSIDEX=6000,LYMSTK=10) INTEGER MINDEX(MMIDEX),SINDEX(MSIDEX),PMODEL,PSCLST,MOFFST, & & YMSTCK(3,LYMSTK),TOPYMS COMMON /INDEX1/ MINDEX,PMODEL,PSCLST,MOFFST,YMSTCK,TOPYMS
There is no declaration as to any alignment. We do use /align:rec1byte
The message that Visual Studio gives:
Exception thrown at 0x4B426F3 (kbcunitop.dll) in Petro-SIM.exe: 0xC000005: Access violation reading location 0xFFFFFFFF
Does not seem consistent with the instruction at that address either, which is another odd thing.
There are no relevant DEC declarations involved.
And we have many thousands of Fortran files that get compiled and linked in. The problem only happens in this one file.
Maybe it is that the indexes definition are common and included somewhere else with some sort of compiler option?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Sadly that definition is included in about 406 Fortran fies, and many of them include other things above or below it.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
benifck,
It is possible that error has nothing to do with your code. Assuming the error message is correct, then the only likely candidate is that BDINDX had been entered at a non-instruction start address via an errant branch.
Can you determine if this occurs on the first call or after the first call?
Can you determine if this occurs during a call or exclusive of a call?
Careful, if the cause is external to the code itself, then any changes (e.g. adding a PRINT trace) may make the symptoms move elsewhere. An then this may make it difficult to locate the source of the problem.
Regardless of the above questions, movdqa is a instruction that requires the _mm128 argument to be on a 16-byte aligned address. Per your disassembly listing it is not.
As an alternative work around, you could compiler this one file with /Qvec-
If this corrects the problem, then this indeed is indicative of a compiler code generation problem and should be reported to the Premier Support site.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Can you determine if this occurs during a call or exclusive of a call?
> Yes, it is on the very first call. 100% repeatable.
Can you determine if this occurs during a call or exclusive of a call?
> This happens during a normal proper execution of a call. The call stack and everything seems fine and as expected.
My guess is that the Intel compiler is somehow optimizing incorrectly or that somehow MINDEX is not on a 16 byte boundary as the compiler expected. What could cause that? Some DEC setting for which I can search? Is it somehow included in a Fortran file elsewhere which causes this? Is there a DEC align option that I can search for? Maybe the compiler sees one where it actually handles MINDEX but then when it compiles this routine it assumes it is aligned? Yes in my standalone setup I cannot make it generate the same assembly language. Will try a few more times.
As for the error message, I suspect visual studio is generating a wrong error message.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
MINDEX is an integer array at the beginning of COMMON, so I would expect it to be 32 or even 64-byte aligned. If you open a memory window and ask for LOC(MINDEX), what address does it show you?
When you look to see which instruction is at fault, is this in the same run that gets the error? (In other words, are you running in the debugger and it faults there?) I ask because the load addresses will vary between runs due to Address Space Layout Randomization.
It would be interesting to set a breakpoint on that instruction (you may have to stop in the routine first and then find it) and see what the values of register ecx is before the instruction executes. Also interesting to see if it crashes the first time it hits that instruction or sometime later.
But it may well be that the compiler is improperly making an assumption here about alignment. If so, we'd need a complete test case to show the developers.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page