Bug 56471 - Program crashes when allocating a derived type with an allocatable component
Program crashes when allocating a derived type with an allocatable component
Status: NEW
Product: gcc
Classification: Unclassified
Component: fortran
4.8.0
: P3 normal
: ---
Assigned To: Not yet assigned to anyone
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2013-02-27 10:18 UTC by Vladimir Fuka
Modified: 2013-06-29 21:55 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2013-06-29 00:00:00


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

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.
COLLECT_GCC=gfortran
COLLECT_LTO_WRAPPER=/usr/local/gcc-4.8/lib/gcc/x86_64-unknown-linux-gnu/4.8.0/lto-wrapper
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'
COMPILER_PATH=/usr/local/gcc-4.8/lib/gcc/x86_64-unknown-linux-gnu/4.8.0/:/usr/local/gcc-4.8/lib/gcc/x86_64-unknown-linux-gnu/4.8.0/:/usr/local/gcc-4.8/lib/gcc/x86_64-unknown-linux-gnu/:/usr/local/gcc-4.8/lib64/gcc/x86_64-unknown-linux-gnu/4.8.0/:/usr/local/gcc-4.8/lib64/gcc/x86_64-unknown-linux-gnu/
LIBRARY_PATH=/usr/local/gcc-4.8/lib64/gcc/x86_64-unknown-linux-gnu/4.8.0/:/usr/local/gcc-4.8/lib64/gcc/x86_64-unknown-linux-gnu/4.8.0/../../../../lib64/:/lib/../lib64/:/usr/lib/../lib64/:/opt/intel/composer_xe_2013.1.117/compiler/lib/intel64/:/opt/intel/composer_xe_2013.1.117/ipp/../compiler/lib/intel64/:/opt/intel/composer_xe_2013.1.117/ipp/lib/intel64/:/opt/intel/composer_xe_2013.1.117/compiler/lib/intel64/:/opt/intel/composer_xe_2013.1.117/mkl/lib/intel64/:/opt/intel/composer_xe_2013.1.117/tbb/lib/intel64/:/usr/local/gcc-4.8/lib64/gcc/x86_64-unknown-linux-gnu/4.8.0/../../../:/lib/:/usr/lib/
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
  allocate(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 (...);
        }
      else
        {
          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);
        L.1:;
        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== 
==28612== Can't extend stack to 0x7fc9d95e0 during signal delivery for thread 1:
==28612==   no stack segment
==28612== 
==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.