Bug 56471 - Program crashes when allocating a derived type with an allocatable component
Summary: Program crashes when allocating a derived type with an allocatable component
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 7.1.1
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
Depends on:
Reported: 2013-02-27 10:18 UTC by Vladimir Fuka
Modified: 2017-09-20 22:04 UTC (History)
4 users (show)

See Also:
Known to work:
Known to fail: 6.0
Last reconfirmed: 2015-10-24 00:00:00

reproduction source file (357 bytes, text/x-fortran)
2013-02-27 10:18 UTC, Vladimir Fuka

Note You need to log in before you can comment on or make changes to this bug.
Description Vladimir Fuka 2013-02-27 10:18:44 UTC
Created attachment 29547 [details]
reproduction source file

The attached program crashes when executing the allocate statement. Originally reported in http://stackoverflow.com/questions/15107976/why-does-the-following-fortran-code-allocate-on-the-stack-heap-depending-on-the

gfortran -v allocate.f90 -fcheck=all -fbacktrace -g -gdwarf-3
Driving: gfortran -v allocate.f90 -fcheck=all -fbacktrace -g -gdwarf-3 -l gfortran -l m -shared-libgcc
Using built-in specs.
Target: x86_64-unknown-linux-gnu
Configured with: ../gcc-4.8-20130224/configure --enable-languages=c,c++,fortran --with-cloog --prefix=/usr/local/gcc-4.8
Thread model: posix
gcc version 4.8.0 20130224 (experimental) (GCC) 
COLLECT_GCC_OPTIONS='-v' '-fcheck=all' '-fbacktrace' '-g' '-gdwarf-3' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
 /usr/local/gcc-4.8/lib/gcc/x86_64-unknown-linux-gnu/4.8.0/f951 allocate.f90 -quiet -dumpbase allocate.f90 -mtune=generic -march=x86-64 -auxbase allocate -g -gdwarf-3 -version -fcheck=all -fbacktrace -fintrinsic-modules-path /usr/local/gcc-4.8/lib64/gcc/x86_64-unknown-linux-gnu/4.8.0/finclude -o /tmp/cc6wTJXo.s
GNU Fortran (GCC) version 4.8.0 20130224 (experimental) (x86_64-unknown-linux-gnu)
        compiled by GNU C version 4.8.0 20130224 (experimental), GMP version 5.0.5, MPFR version 3.1.0-p1, MPC version 0.8.2
GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096
GNU Fortran (GCC) version 4.8.0 20130224 (experimental) (x86_64-unknown-linux-gnu)
        compiled by GNU C version 4.8.0 20130224 (experimental), GMP version 5.0.5, MPFR version 3.1.0-p1, MPC version 0.8.2
GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096
COLLECT_GCC_OPTIONS='-v' '-fcheck=all' '-fbacktrace' '-g' '-gdwarf-3' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
 as -v --64 -o /tmp/ccSfTbSl.o /tmp/cc6wTJXo.s
GNU assembler version 2.22 (x86_64-suse-linux) using BFD version (GNU Binutils; openSUSE 12.2) 2.22
Reading specs from /usr/local/gcc-4.8/lib64/gcc/x86_64-unknown-linux-gnu/4.8.0/../../../../lib64/libgfortran.spec
rename spec lib to liborig
COLLECT_GCC_OPTIONS='-v' '-fcheck=all' '-fbacktrace' '-g' '-gdwarf-3' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
COLLECT_GCC_OPTIONS='-v' '-fcheck=all' '-fbacktrace' '-g' '-gdwarf-3' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
 /usr/local/gcc-4.8/lib/gcc/x86_64-unknown-linux-gnu/4.8.0/collect2 --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 /usr/lib/../lib64/crt1.o /usr/lib/../lib64/crti.o /usr/local/gcc-4.8/lib64/gcc/x86_64-unknown-linux-gnu/4.8.0/crtbegin.o -L/usr/local/gcc-4.8/lib64/gcc/x86_64-unknown-linux-gnu/4.8.0 -L/usr/local/gcc-4.8/lib64/gcc/x86_64-unknown-linux-gnu/4.8.0/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/opt/intel/composer_xe_2013.1.117/compiler/lib/intel64 -L/opt/intel/composer_xe_2013.1.117/ipp/../compiler/lib/intel64 -L/opt/intel/composer_xe_2013.1.117/ipp/lib/intel64 -L/opt/intel/composer_xe_2013.1.117/compiler/lib/intel64 -L/opt/intel/composer_xe_2013.1.117/mkl/lib/intel64 -L/opt/intel/composer_xe_2013.1.117/tbb/lib/intel64 -L/usr/local/gcc-4.8/lib64/gcc/x86_64-unknown-linux-gnu/4.8.0/../../.. /tmp/ccSfTbSl.o -lgfortran -lm -lgcc_s -lgcc -lquadmath -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/local/gcc-4.8/lib64/gcc/x86_64-unknown-linux-gnu/4.8.0/crtend.o /usr/lib/../lib64/crtn.o

:~/f/errors> ./a.out 
Neoprávněný přístup do paměti (SIGSEGV)
Comment 1 janus 2013-02-27 11:55:37 UTC
Reduced test case:

program main
  implicit none    
    type :: containerType
    real, dimension(10000000) ::  arrayData 
    integer, allocatable :: allo
  end type
  type (containerType),allocatable :: container
end program

Note: The allocatable component does not have to be CHARACTER, but the array needs to be very large in order to trigger the error. The generated code is:

      container = 0B;
      if ((logical(kind=4)) __builtin_expect ((integer(kind=8)) (container != 0B), 0))
          _gfortran_runtime_error_at (...);
          container = (struct containertype *) __builtin_malloc (40000008);
          if ((logical(kind=4)) __builtin_expect ((integer(kind=8)) (container == 0B), 0))
              _gfortran_os_error (...);
      container->allo = 0B;
        struct containertype containertype.0;

        if (container != 0B) goto L.1;
        container = (struct containertype *) __builtin_calloc (1, 40000008);
        containertype.0.allo = 0B;
        *container = containertype.0;

I don't really understand why 'container' is being allocated twice: Once with __builtin_malloc and once with __builtin_calloc. Looks like we're leaking memory here.

Valgrind reports:

==28612== Warning: client switching stacks?  SP change: 0x7fefffbe0 --> 0x7fc9da1d0
==28612==          to suppress, use: --max-stackframe=40000016 or greater
==28612== Invalid write of size 8
==28612==    at 0x4008E5: MAIN__ (in /home/jweil/GSoC/PRs/56471/a.out)
==28612==    by 0x4009D2: main (in /home/jweil/GSoC/PRs/56471/a.out)
==28612==  Address 0x7fc9da1c8 is on thread 1's stack
==28612== Can't extend stack to 0x7fc9d95e0 during signal delivery for thread 1:
==28612==   no stack segment
==28612== Process terminating with default action of signal 11 (SIGSEGV)
==28612==  Access not within mapped region at address 0x7FC9D95E0
==28612==    at 0x4008E5: MAIN__ (in /home/jweil/GSoC/PRs/56471/a.out)
==28612==  If you believe this happened as a result of a stack
==28612==  overflow in your program's main thread (unlikely but
==28612==  possible), you can try to increase the size of the
==28612==  main thread stack using the --main-stacksize= flag.
==28612==  The main thread stack size used in this run was 8388608.

Indeed the segfault seems to be due to a stack overflow.
Comment 2 Joost VandeVondele 2015-10-24 15:11:09 UTC
yes, stack overflow also with trunk.

> gfortran -fsanitize=address -g PR56471.f90 && ./a.out
==13127==ERROR: AddressSanitizer: stack-overflow on address 0x7ffe797483b8 (pc 0x000000400b73 bp 0x7ffe7bd6ddd0 sp 0x7ffe797483b0 T0)
    #0 0x400b72 in MAIN__ /data/vjoost/gnu/bugs/PR56471.f90:2
    #1 0x400d0a in main /data/vjoost/gnu/bugs/PR56471.f90:10
    #2 0x3ba4a1ed5c in __libc_start_main (/lib64/libc.so.6+0x3ba4a1ed5c)
    #3 0x400a78  (/data/vjoost/gnu/bugs/a.out+0x400a78)

SUMMARY: AddressSanitizer: stack-overflow /data/vjoost/gnu/bugs/PR56471.f90:2 in MAIN__
Comment 3 Walter Spector 2017-09-20 22:04:49 UTC
Adding myself to the ticket.  Here is another simple example using the trunk as of today:

wws@w6ws-4:/tmp$ cat allscal.f90
program allscal
  implicit none

  type mytype_t
    character(32), allocatable :: typescalar
  end type

  type (mytype_t), allocatable :: myobj

  allocate (myobj)
  allocate (myobj%typescalar)
  myobj%typescalar = 'hello world'
  print *, myobj%typescalar
  deallocate (myobj%typescalar)
  deallocate (myobj)

end program
wws@w6ws-4:/tmp$ /usr/local/gcc-trunk/bin/gfortran -g allscal.f90
wws@w6ws-4:/tmp$ echo $LD_LIBRARY_PATH
wws@w6ws-4:/tmp$ a.out

Program received signal SIGSEGV: Segmentation fault - invalid memory reference.

Backtrace for this error:
#0  0x7f3e526c44af in ???
#1  0x4008c5 in allscal
	at /tmp/allscal.f90:10
#2  0x400b19 in main
	at /tmp/allscal.f90:17
Segmentation fault (core dumped)
wws@w6ws-4:/tmp$ /usr/local/gcc-trunk/bin/gfortran --version
GNU Fortran (GCC) 8.0.0 20170920 (experimental)
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO