- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I try to recompile a project worked well under IFORT with the new IFX compiler. Calling the WriteConsoleOutputAttribute trigers an access violation. The function call is:
SCR_OutAtt = WriteConsoleOutputAttribute(SCR%OutputHandle, Loc(lpAttribute), nLength, dwWriteCoord, lpNumberOfCharsWritten)
Here are the parameters:
Name Value Type
scr%OutputHandle | 104 | INTEGER(8) | |
lpAttribute | 7 | INTEGER(8) | |
nlength | 47 | INTEGER(4) | |
◢ | dwWriteCoord | {...} | TYPE(TKLIBMOD::T_COORD) |
dwWriteCoord%X | 1 | INTEGER(2) | |
dwWriteCoord%Y | 1 | INTEGER(2) | |
lpNumberOfCharsWritten | 0 | INTEGER(8) |
What is wrong? According to KERNEL32.f90 the parameter declarations are correct.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@TiborKibedi1, with your scaled down reproducer, TkLib_Test.f90, I get an access violation like you do when compiling with ifx 2024.0.0.
BUT there's good news! With ifx 2024.1.0, it runs successfully, assuming this is the output you expect:
Q:\06175490>TkLib_Test.exe
* * * TkLibTest * * *
Look for this new compiler in the next week or so.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Please attach a minimal but complete example source.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks Steve for looking into this. I made a fresh installation of VS, One-Api and the Intel Compiler, but the problem still persists.
Attached is the source and project files. It was compiled and linked using MS VS 2022 17.9.4, One-API and IFX 2024.0.
The access violation happens at line 450 in TK_LibMod.f90.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Well I think you mean this line:
SCR_OutAtt = WriteConsoleOutputAttribute(SCR%OutputHandle, Loc(lpAttribute), nLength, dwWriteCoord, lpNumberOfCharsWritten)
The last parameter _Out_ LPDWORD lpNumberOfAttrsWritten is meant to be an integer pointer to a dword so if you have:
integer(dword) :: Numbeofchars
you need to pass loc(Numbeofchars) and the function will write to that address. Dword is 4 bytes but the address is 8 bytes whicg is probs where it violates.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am still having problems calling the WriteConsoleOutputAttribute(SCR%OutputHandle, Loc(SCR%Attributes), nLength, dwWriteCoord, Loc(NumberOfChars)) function. I followed the interface declaration in the KERNEL32.f90 module:
INTERFACE
FUNCTION WriteConsoleOutputAttribute( &
hConsoleOutput, &
lpAttribute, &
nLength, &
dwWriteCoord, &
lpNumberOfAttrsWritten)
import
integer(BOOL) :: WriteConsoleOutputAttribute ! BOOL
!DEC$ ATTRIBUTES DEFAULT, STDCALL, DECORATE, ALIAS:'WriteConsoleOutputAttribute' :: WriteConsoleOutputAttribute
integer(HANDLE) hConsoleOutput ! HANDLE hConsoleOutput
integer(LPWORD) lpAttribute ! WORD* lpAttribute
integer(DWORD) nLength ! DWORD nLength
TYPE (T_COORD) dwWriteCoord ! COORD dwWriteCoord
integer(LPDWORD) lpNumberOfAttrsWritten ! LPDWORD lpNumberOfAttrsWritten
END FUNCTION
END INTERFACE
The variables in my code are declared as
Integer(HANDLE) SCR%OutputHandle
Integer(LPWORD) SCR%Attributes
Integer(DWORD) nLength
Type (T_COORD) dwWriteCoord
Integer(LPDWORD) NumberOfChars
Declaring "NumberOfChars" as DWORD makes no difference. The same code, initially developed and worked under previous versions of Intel Fortran and the problem surface with the latest version, when the IFX compiler is being used. Interestingly, switching to IFORT in the latest distribution, the code works.
It may indicate a bug in the IFX compiler. Attached is a cut down version of the code.
I am using Win11, VS 2022, Intel oneAPI 2024.0, Intel Fortran Compiler 2024.0
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Indeed, ifx does have a bug, but it is subtle.
The problem relates to the fourth argument, which is a structure of type T_COORD passed by value. T_COORD has two components that are 16-bit integers, so a single value of type T_COORD is 32 bits. The Windows API expects to receive this by-value, with the 32 bits passed in register R9; ifort does this, However, ifx doesn't want to pass this by value and instead passes something else, which causes it to try to write to improper locations in the console buffer.
I wrote a small test program to demonstrate this, but first wanted to see if using BIND(C) and VALUE rather than ATTRIBUTES STDCALL showed the same bug - it did not.
Here's the minimal example (sources attached). Just to make sure there was no issue with inlining, I put the subroutine in a separate source. I also have some evidence that ifx improperly receives a 32-bit structure when STDCALL is in effect.
struct.f90
module ctypes
use, intrinsic :: ISO_FORTRAN_ENV
type COORD_T
integer(INT16) :: X, Y
end type COORD_T
end module ctypes
program struct_test
use ctypes
implicit none
type(COORD_T) :: COORD
interface
subroutine sub (COORD)
import
!DIR$ ATTRIBUTES STDCALL :: sub
type(COORD_T), VALUE :: COORD
end subroutine sub
end interface
COORD = COORD_T (314,159)
call sub (COORD)
end
sub.f90
subroutine sub (A,B,C,COORD) BIND(C)
use ctypes
implicit none
integer, value :: A,B,C
type(COORD_T), value :: COORD
print '(2I6)', COORD
end subroutine sub
D:\Projects>ifort /c /Qdiag-disable:10448 sub.f90
Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel(R) 64, Version 2021.11.1 Build 20231117_000000
Copyright (C) 1985-2023 Intel Corporation. All rights reserved.
D:\Projects>ifort /Qdiag-disable:10448 struct.f90 sub.obj
Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel(R) 64, Version 2021.11.1 Build 20231117_000000
Copyright (C) 1985-2023 Intel Corporation. All rights reserved.
Microsoft (R) Incremental Linker Version 14.39.33522.0
Copyright (C) Microsoft Corporation. All rights reserved.
-out:struct.exe
-subsystem:console
struct.obj
sub.obj
D:\Projects>struct.exe
314 159
D:\Projects>ifx -c sub.f90
Intel(R) Fortran Compiler for applications running on Intel(R) 64, Version 2024.0.2 Build 20231213
Copyright (C) 1985-2023 Intel Corporation. All rights reserved.
D:\Projects>ifx struct.f90 sub.obj
Intel(R) Fortran Compiler for applications running on Intel(R) 64, Version 2024.0.2 Build 20231213
Copyright (C) 1985-2023 Intel Corporation. All rights reserved.
Microsoft (R) Incremental Linker Version 14.39.33522.0
Copyright (C) Microsoft Corporation. All rights reserved.
-out:struct.exe
-subsystem:console
struct.obj
sub.obj
D:\Projects>struct.exe
314 0
The only solution for now is to keep using ifort.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
There are some issues with the example shown above. The interface for sub does not have BIND(C) specified and the arguments do not match the implementation (A,B,C??). If I also add BIND(C) to the type definition and remove A,B,C from sub it runs and gives the correct answer.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I do think you have a bug in your code, however. From what I'm reading, the routine expects to read nLength attributes, but your data structure has only one, so it will write random data to the other positions' attributes.
I did think of a workaround, which is to declare your own interface to WriteConsoleOutputAttribute that uses BIND(C) and VALUE instead of STDCALL - obviously this would be for x64 only. I have not tested this but I think it would work. But I still think it's better to keep using ifort for now.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Steve,
Then would you/we assume that any user defined type that has sizeof of 1, 2, 4, 8 bytes (same sizeof as native types), passed by value to bind(C) procedure, would experience the problem with ifx (as of 3/25/24 or earlier release)?
If so, I can see a lot of code breaking. I am surprised this issue hasn't shown up much on this forum.
Jim
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The example was contrived to demonstrate the problem. Removing A, B and C hides the issue.
Yes, anything up to 8 bytes should be passed by value when the STDCALL convention is in effect. I believe MSVC does this even for the C convention. I have not looked to see what convention is used on Linux. ifort does it right, ifx does not.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@Steve_Lionel, I'm having trouble getting the same answers as you do with your reproducer using ifort.
Q:\tmp>ifort /Qdiag-disable:10448 -what struct.f90 sub.f90
Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel(R) 64, Version 2021.11.0 Build 20231010_000000
Copyright (C) 1985-2023 Intel Corporation. All rights reserved.
Intel(R) Fortran 2021.11.0-1242.01
Intel(R) Fortran 2021.11.0-1242.01
Microsoft (R) Incremental Linker Version 14.38.33130.0
Copyright (C) Microsoft Corporation. All rights reserved.
-out:struct.exe
-subsystem:console
struct.obj
sub.obj
Q:\tmp>struct.exe
256 0
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@Barbara_P_Intel Don't compile them together - do it separately as I did. However, I find the result you did get to be wrong as well - I can't reproduce that.
D:\Projects>ifort /Qdiag-disable:10448 -what struct.f90 sub.f90
Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel(R) 64, Version 2021.11.1 Build 20231117_000000
Copyright (C) 1985-2023 Intel Corporation. All rights reserved.
Intel(R) Fortran 2021.11.1-1242.01
Intel(R) Fortran 2021.11.1-1242.01
Microsoft (R) Incremental Linker Version 14.39.33522.0
Copyright (C) Microsoft Corporation. All rights reserved.
-out:struct.exe
-subsystem:console
struct.obj
sub.obj
D:\Projects>struct.exe
314 159
D:\Projects>ifx -c -what sub.f90
Intel(R) Fortran Compiler for applications running on Intel(R) 64, Version 2024.0.2 Build 20231213
Copyright (C) 1985-2023 Intel Corporation. All rights reserved.
Intel(R) Fortran 24.0-1238.2
D:\Projects>ifx -what struct.f90 sub.obj
Intel(R) Fortran Compiler for applications running on Intel(R) 64, Version 2024.0.2 Build 20231213
Copyright (C) 1985-2023 Intel Corporation. All rights reserved.
Intel(R) Fortran 24.0-1238.2
Microsoft (R) Incremental Linker Version 14.39.33522.0
Copyright (C) Microsoft Corporation. All rights reserved.
-out:struct.exe
-subsystem:console
struct.obj
sub.obj
D:\Projects>struct.exe
314 0
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I just realized that I posted the wrong version of the source. The module ctypes should be in sub.f90, not struct.f90! Sorry for the confusion.
sub.f90
module ctypes
use, intrinsic :: ISO_FORTRAN_ENV
type COORD_T
integer(INT16) :: X, Y
end type COORD_T
end module ctypes
subroutine sub (A,B,C,COORD) BIND(C)
use ctypes
implicit none
integer, value :: A,B,C
type(COORD_T), value :: COORD
print '(2I6)', COORD
end subroutine sub
struct.f90
program struct_test
use ctypes
implicit none
type(COORD_T) :: COORD
interface
subroutine sub (A,B,C,COORD)
import
!DIR$ ATTRIBUTES STDCALL :: sub
integer :: A,B,C
type(COORD_T):: COORD
end subroutine sub
end interface
COORD = COORD_T (314,159)
call sub (1,2,3,COORD)
end
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks, @Steve_Lionel, for the update to your reproducer. ifx outputs the same wrong answers for me now with the latest release, 2024.0.0.
The better news is that with a preview of 2024.1.0 ifx prints the same right answers as ifort.
Look for that release in the next week or so.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@TiborKibedi1, with your scaled down reproducer, TkLib_Test.f90, I get an access violation like you do when compiling with ifx 2024.0.0.
BUT there's good news! With ifx 2024.1.0, it runs successfully, assuming this is the output you expect:
Q:\06175490>TkLib_Test.exe
* * * TkLibTest * * *
Look for this new compiler in the next week or so.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page