Incorrect intent declarations in Fortran bindings
Anke Kreuzer recently reported a segmentation fault originating in a call to fsion_paropen_mpi
.
Hallo Benedikt,
also der Code rund um das FSION_PAROPEN_MPI sieht so aus aus:
fsblksize = -1 chunksize = INT(16+nt*(96+120*ndl),KIND=8)
IF(myid==0) THEN WRITE(*,*) " Before create_Com" ENDIF color = crank/24 key = modulo(crank,24);
! WRITE(,) "My id: ",myid , "color: ", color, "key: ", key
CALL MPI_COMM_SPLIT(MPI_COMM_WORLD, color, myid, & lcomm, ierr) IF(myid==0) THEN WRITE(,) " After create_Com, before SION_PAROPEN_MPI" ENDIF
So, bis hier hin laeuft das Programm durch und dann kommt:
CALL FSION_PAROPEN_MPI('NAM_CPs', & 'bw',-1,icomm0,lcomm, & chunksize, fsblksize, myid, newfname, sid)
IF(myid==0) THEN WRITE(*,*) " After paropen" ENDIF
Und diese letzte Ausgabe wird nie ausgegeben, da vorher der Segmentation fault passiert.
The problem is that SIONlib tries to return the number of files it actually opened (based on the number of distinct local communicators) in the nfiles
argument. However, the special value -1
is specified as an integer literal and as the dummy argument nfiles
is declared with intent(in)
is probably placed in a read-only part of memory.
A quick inspection reveals that the intent
declarations on the Fortran subroutine and the argument const-ness on the C function that is called underneath differ in several places.
subroutine fsion_paropen_mpi(fname,file_mode,nfiles,fgcomm,flcomm,chunksizes,fsblksize,&
& globalrank,newfname,sid)
implicit none
character(len=*), intent(in) :: fname
character(len=*), intent(in) :: file_mode
integer, intent(in) :: nfiles
integer, intent(in) :: fgcomm
integer, intent(inout) :: flcomm
integer*8, intent(inout) :: chunksizes
integer*4, intent(inout) :: fsblksize
integer, intent(in) :: globalrank
character(len=*), intent(out) :: newfname
integer, intent(out) :: sid
call fsion_paropen_mpi_c(fname,file_mode,nfiles,fgcomm,flcomm,chunksizes,fsblksize,&
& globalrank,newfname,sid)
end subroutine fsion_paropen_mpi
void fsion_paropen_mpi_c(char *fname,
char *file_mode,
int *numFiles,
MPI_Fint * fgComm,
MPI_Fint * flComm,
sion_int64 *chunksize,
sion_int32 *fsblksize,
int *globalrank,
char *newfname,
int *sid,
int fname_len,
int file_mode_len,
int newfname_len);