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

segfault with -init=arrays and arrays with more than 2^31 elements

cagey
Beginner
381 Views

The following code segfaults when compiled with -init=arrays (ifx 2025.1.0 20250317, debian12 and fedora41)

program boolarraytest
use, intrinsic :: iso_fortran_env, only: logical8,int64
implicit none
logical(logical8), allocatable :: l(:)
integer(int64) :: b
b=2**31
allocate(l(0:b),source=.false._logical8)
print *,l(1)
end program boolarraytest

 

ifx -i8 \
-align array64byte \
-fpp \
-warn nounused,declarations,interface,usage,errors \
-DDEBUG \
-init=zero,arrays \
-fma -fpconstant \
-fp-model=precise \
-g \
-fno-omit-frame-pointer \
-traceback \
-check all,nouninit,noarg_temp_created \
-qoverride-limits \
-qopt-matmul \
bool-array-alloc.f90

Yes, I know there's way too much on the compile line for the given code.  It's a reproducible example from a much bigger program.

Taking out the "arrays" from the -init clause or reducing the size to 2**30 succeeds.

0 Kudos
7 Replies
jimdempseyatthecove
Honored Contributor III
274 Views

Try changing

b=2**31
to
b=2_int64**31

Jim Dempsey

 

cagey
Beginner
247 Views

It doesnt solve the problem.  It still segfaults at allocate.

0 Kudos
Ron_Green
Moderator
234 Views

I maybe marked Jim's answer as SOLUTION too fast.  Jim is correct, your integer expression needed a correction.  But on top of that, there actually is a problem with

-init=zero,arrays

that's the cause.  if you set this to:

-init=zero,noarrays

no seg fault.

I would guess the init zero for a large array > 2GB is using  unsigned 32bit offset logic.  Definitely a bug.  I'll write it up.

 

test modified:

program boolarraytest
use, intrinsic :: iso_fortran_env, only: logical8,int64
implicit none
logical(logical8), allocatable :: l(:)
integer(int64) :: b
integer :: istat
character*256 :: cmsg=''

b=2**31
print*, "b 2**31", b
b=2_int64**31
print*, "b 2_int64**31", b
allocate(l(0:b),source=.false._logical8,STAT=istat,ERRMSG=cmsg)
print *, istat, trim(cmsg)
print *, l(1), l(b)
end program boolarraytest

 

Compile and run command, minimum subset of options

rm ./a.out ; ifx -O0  -init=zero,arrays segv.f90 ; ./a.out

 b 2**31           -2147483648
 b 2_int64**31            2147483648
forrtl: severe (174): SIGSEGV, segmentation fault occurred
Image              PC                Routine            Line        Source             
libc.so.6          000014FCF3AC1520  Unknown               Unknown  Unknown
a.out              000000000045F0F1  __intel_avx_rep_m     Unknown  Unknown
a.out              000000000040591C  Unknown               Unknown  Unknown
a.out              0000000000405CAA  Unknown               Unknown  Unknown
a.out              0000000000405492  Unknown               Unknown  Unknown
a.out              000000000040520D  Unknown               Unknown  Unknown
libc.so.6          000014FCF3AA8D90  Unknown               Unknown  Unknown
libc.so.6          000014FCF3AA8E40  __libc_start_main     Unknown  Unknown
a.out              0000000000405125  Unknown               Unknown  Unknown

 

0 Kudos
cagey
Beginner
220 Views

Initializing the arrays is what I was trying to achieve.  I'm chasing a segfault that smells like something is not initialized as it sometimes crashes and sometimes it doesn't.  I hit this problem well before I got to the point that the big program segfaulted.

Wouldn't it be signed 32bit integer as unsigned should go to 4GB?  The array is only 1 byte over 2GB.

The other thought would be - if I specified a source to initialize the array, why does the flag do anything?

0 Kudos
Ron_Green
Moderator
157 Views

Yes, I meant signed integer.  My mistake in the response above.

 

So you raise a good question - you use -g -traceback.  That will show you where the segfault occurs.  but you are trying to find an anomaly before that point in the code perhaps.

a couple of thoughts 

First, ifx is different than ifort for default behavior when integers overflow.  Read https://www.intel.com/content/www/us/en/docs/fortran-compiler/developer-guide-reference/2025-1/fstrict-overflow-qstrict-overflow.html

If you expect or check integers going negative due to "expected" overflow from positive to negative, your legacy code may not work by default.  If you do want integer overflow to 2s complement:
-fno-strict-overflow

 

I see you are using -i8

Understand that this will NOT affect any integer declared:
integer*4

The "star"size tells the compiler exactly how many bytes for the data and ignores compiler options.  

 

you should investigate the -fsanitize options address and memory.  Address works with any application.  Memory you have to recompile ALL code and dependent libraries with this option, however.  So if you have an external DLL lib that you don't have source for this will not work.

 

 

0 Kudos
Ron_Green
Moderator
157 Views

Since you asked, SOURCE= can create an array temp.  The initial temp array is initialized based on the init flag BEFORE the values of .false. are added to it.  INIT is done at ALLOCATE time irregardless of how the temporary is to be used. Make sense?  INIT affects what happens immediately after allocation, it is part of the allocation process.

0 Kudos
Ron_Green
Moderator
126 Views

I modified the case to remove the SOURCE=.  still segfaults.  so it is actually the allocation followed by the init to zero that is at fault.  SOURCE= was not the root cause.

bug ID CMPLRLLVM-67957

0 Kudos
Reply
OSZAR »