このサンプルに縮小できる従来の Fortran コードに問題があります。
program main
implicit none
write(6,*) 'Hello!'
end program main
subroutine bigdata()
implicit none
!real*8 AA(50292712)
real*8 AA(50292713)
common /big_common/ AA
end subroutine
サブルーチンがプログラムから呼び出されることはないことに注意してください。これを 64 ビット マシンでコンパイルして実行すると、次のようになります。
$ gfortran -fsanitize=address main.f ; ./a.out
Hello!
$ gfortran -m32 main.f ; ./a.out
Hello!
$ gfortran -m32 -fsanitize=address main.f ; ./a.out
==32656== Shadow memory range interleaves with an existing memory mapping. ASan cannot proceed correctly. ABORTING.
==32656== Process memory map follows:
0x08048000-0x08049000 /home/username/a.out
0x08049000-0x0804a000 /home/username/a.out
0x0804a000-0x0804b000 /home/username/a.out
0x0804b000-0x1ffff000
0xf5d77000-0xf5d78000
0xf5d78000-0xf5dbc000 /lib/i386-linux-gnu/libm-2.19.so
0xf5dbc000-0xf5dbd000 /lib/i386-linux-gnu/libm-2.19.so
0xf5dbd000-0xf5dbe000 /lib/i386-linux-gnu/libm-2.19.so
0xf5dbe000-0xf5dbf000
0xf5dbf000-0xf5e38000 /usr/lib32/libquadmath.so.0.0.0
0xf5e38000-0xf5e39000 /usr/lib32/libquadmath.so.0.0.0
0xf5e39000-0xf5e3a000 /usr/lib32/libquadmath.so.0.0.0
0xf5e3a000-0xf5e56000 /lib/i386-linux-gnu/libgcc_s.so.1
0xf5e56000-0xf5e57000 /lib/i386-linux-gnu/libgcc_s.so.1
0xf5e57000-0xf5e5a000 /lib/i386-linux-gnu/libdl-2.19.so
0xf5e5a000-0xf5e5b000 /lib/i386-linux-gnu/libdl-2.19.so
0xf5e5b000-0xf5e5c000 /lib/i386-linux-gnu/libdl-2.19.so
0xf5e5c000-0xf5e74000 /lib/i386-linux-gnu/libpthread-2.19.so
0xf5e74000-0xf5e75000 /lib/i386-linux-gnu/libpthread-2.19.so
0xf5e75000-0xf5e76000 /lib/i386-linux-gnu/libpthread-2.19.so
0xf5e76000-0xf5e78000
0xf5e78000-0xf6020000 /lib/i386-linux-gnu/libc-2.19.so
0xf6020000-0xf6022000 /lib/i386-linux-gnu/libc-2.19.so
0xf6022000-0xf6023000 /lib/i386-linux-gnu/libc-2.19.so
0xf6023000-0xf6027000
0xf6027000-0xf6123000 /usr/lib32/libgfortran.so.3.0.0
0xf6123000-0xf6124000 /usr/lib32/libgfortran.so.3.0.0
0xf6124000-0xf6125000 /usr/lib32/libgfortran.so.3.0.0
0xf6125000-0xf6151000 /usr/lib32/libasan.so.0.0.0
0xf6151000-0xf6152000 /usr/lib32/libasan.so.0.0.0
0xf6152000-0xf6153000 /usr/lib32/libasan.so.0.0.0
0xf6153000-0xf7705000
0xf7731000-0xf773b000
0xf773b000-0xf773c000 [vdso]
0xf773c000-0xf775c000 /lib/i386-linux-gnu/ld-2.19.so
0xf775c000-0xf775d000 /lib/i386-linux-gnu/ld-2.19.so
0xf775d000-0xf775e000 /lib/i386-linux-gnu/ld-2.19.so
0xff80a000-0xff82c000 [stack]
==32656== End of process memory map.
gfortran バージョン:
$ gfortran -v
Using built-in specs.
COLLECT_GCC=gfortran
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.8/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.8.4-2ubuntu1~14.04.1' --with-bugurl=file:///usr/share/doc/gcc-4.8/README.Bugs --enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.8 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.8 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --disable-libmudflap --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.8-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04.1)
AA
(私のテストでは)のサイズを 1 減らすと、問題が解消されます。制限サイズは、システムや状況によって異なる場合があります。
私が見る限り、共通ブロックのサイズは 2GB には遠く及ばず、問題が発生すると予想-m32
されます。これはアドレスサニタイザーの制限ですか? この問題を回避するために使用できるコマンド ラインまたはランタイム トリックはありますか?
編集:おそらく共通ブロックとは関係ありませんが、共通ブロック内の配列は使用されなくても割り当てられるという事実とは関係ありません。これにより、同じ問題が発生します。
program main
implicit none
* real*8, allocatable :: AA(:)
* !allocate(AA(378272768))
* allocate(AA(378272769))
!real*8 AA(50292702)
real*8 AA(50292705)
AA(1)=1.0d0
write(6,*) 'Hello!'
end program main
割り付け可能な配列の制限は、静的配列のほぼ 8 倍であることに注意してください。