R. Hassani
R. Hassani

Reputation: 155

problem with a final procedure (segfault with gfortran)

consider the following small program that reproduces the segmentation fault I get with gfortran gcc 9.2.0 for mac os):

module stringmod

   type :: str_t
      character(len=:), allocatable :: s
   contains
      final :: finalize
   end type str_t   

   type :: static_t  
      type(str_t) :: expr(3)
   end type static_t

   type :: dynamic_t  
      type(str_t), allocatable :: expr(:)
   end type dynamic_t

contains

   subroutine finalize ( x )
      type(str_t), intent(in out) :: x

      if (allocated(x%s)) deallocate(x%s)    

   end subroutine finalize

end module stringmod

use stringmod

implicit none

type(static_t ), allocatable :: stat(:)
type(dynamic_t), allocatable :: dyna(:)
integer                      :: i, j, n = 10

allocate(stat(n),dyna(n))

do i = 1, n
   allocate(dyna(i)%expr(3))
end do

! No problem when deallocating "dyna":
deallocate(dyna)

! while deallocating "stat"causes a segfault with gfortran (gcc 9.2.0 for mac os)
! (unless the final method is removed from the DT):

deallocate(stat) 

end

The segfault only occurs when deallocating the array of static_t type which has an explicit array member of str_t type. Strangely, it seems related to the final method of the str_t DT (when I remove this procedure, the problem goes away), but I don't see the reason.

Upvotes: 5

Views: 428

Answers (2)

HendersonSC
HendersonSC

Reputation: 1

First I would comment, but I am not a common user so my rep isn't there. I have a strikingly similar problem and appreciate the precooked example which seems to work with gcc 5.4 accounting for this caveat:

  • default flags, -O1, -O2 all fail
  • -Og and -O3 both work as expected

Obviously this is not something you want to write code to, but wanted to relay my experiences and if you have submitted a bug report this could be useful info for them. I get the same behavior on my Ubuntu laptop with gcc 9.2.1.

Upvotes: 0

francescalus
francescalus

Reputation: 32366

This does look like a problem with final subroutines, after all removing the final subroutine takes the segmentation fault away. However, this is one example of a broader class of problem in gfortran.

For a problem in gfortran it is.

In your case, you have an available workaround: remove the final subroutine which is not actually invoked at any point. In more general cases this may not be an option. Either way, the thing to do is report this bug to the GCC maintainers (especially if you can test with later versions of the compiler).

Why do I say this part of a wider problem? Let's look at simplifying your code:

  type :: str_t
     character, allocatable :: s
  end type str_t

  type :: dynamic_t  
     type(str_t), allocatable :: expr
  end type dynamic_t

  type(dynamic_t), allocatable :: dyna

  allocate(dyna)
  allocate(dyna%expr)

end

or

  implicit none

  type :: str_t
     character, allocatable :: s
  end type str_t

  type :: static_t  
     type(str_t) :: expr
  end type static_t

  type(static_t), allocatable :: stat
  allocate(stat)

end

Neither has finalization to be seen, but both present (to me) segmentation faults when run.

If you want to see a connection between the program of the question and this answer: it is the deferred length nature of the component s which is key. As an explicit-length (allocatable) scalar component the examples above crash with or without finalization; as a deferred length component finalization controls the crash.

Upvotes: 3

Related Questions