https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127738

            Bug ID: 127738
           Summary: caf_shmem: FORM TEAM id collision, segfault on pool
                    exhaustion, leaked shared memory
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libfortran
          Assignee: unassigned at gcc dot gnu.org
          Reporter: jvdelisle at gcc dot gnu.org
  Target Milestone: ---

Thanks to some automated testing:

Three independent defects in libcaf_shmem (-fcoarray=shared), found
while measuring the memory used by coarrays allocated in child teams.
All three reproduce on trunk 20261002.

1. FORM TEAM can pick up the shared data of another team.

_gfortran_caf_form_team derives the id of a team's shared memory from

  (parent lastmemid << image_size_shift) + team_no + teams_count

where teams_count counts the FORM TEAM statements executed so far.
The sum is not unique: forming team number 2 and then team number 1
in the same parent team gives 2 + 0 == 1 + 1, so the second FORM TEAM
finds the image map of the first team.  Depending on the statements
this fails with "Can not assign new image index in FORM TEAM" or "The
NEW_INDEX of FORM TEAMs has to be unique", and it can also join images
into the wrong team.  Forming teams in a loop runs into it easily.

---- team_id.f90 ----
program team_id
  use iso_fortran_env, only : team_type
  implicit none
  type(team_type) :: t1, t2
  integer :: me

  me = this_image ()
  form team (2, t1)
  form team (1, t2)
  change team (t2)
    print '(a,i0,a,i0,a,i0)', 'image ', me, ': team ', team_number (), &
          ', num_images ', num_images ()
  end team
end program team_id
----

$ gfortran -fcoarray=shared team_id.f90 && GFORTRAN_NUM_IMAGES=4 ./a.out
Fortran runtime error: Can not assign new image index in FORM TEAM.
(on every image; expected: each image in team 1 of 4 images)

2. ALLOCATE (stat=) of a coarray does not report an exhausted shared
memory pool.

When the shared memory pool (GFORTRAN_SHARED_MEMORY_SIZE) cannot hold
the coarray, ALLOCATE returns stat=0 and the first access to the
coarray segfaults, instead of the allocation failing with a nonzero
stat (or error termination without stat=).

---- pool_stat.f90 ----
program pool_stat
  implicit none
  integer(8), allocatable :: a(:)[:]
  integer :: st

  st = 0
  ! 8 MiB per image; more than the shared memory pool for 8 images
  allocate (a(1048576)[*], stat=st)
  if (st == 0) then
    a = this_image ()
    print '(a,i0,a)', 'image ', this_image (), ': allocated'
  else
    print '(a,i0,a,i0)', 'image ', this_image (), ': stat ', st
  end if
end program pool_stat
----

$ gfortran -fcoarray=shared -g pool_stat.f90
$ GFORTRAN_NUM_IMAGES=8 GFORTRAN_SHARED_MEMORY_SIZE=32M ./a.out
Program received signal SIGSEGV: Segmentation fault
  at pool_stat.f90:10          (a = this_image ())
With GFORTRAN_SHARED_MEMORY_SIZE=128M all images allocate.

3. The shared memory object is left behind when the program is
stopped by a signal.

Normal termination, STOP, ERROR STOP, FAIL IMAGE and an image killed
by a signal all remove /dev/shm/gfor-shm-<pid>.  When the supervisor
process itself receives SIGTERM or SIGINT (a timeout, ^C), it kills
the images and exits without unlinking the object, so every such run
leaks one; a machine that runs the testsuite collects hundreds of
them.

---- sleep.f90 ----
program sleep_forever
  implicit none
  sync all
  do
  end do
end program sleep_forever

Reply via email to