Почему проверка времени выполнения gfortran не работает при передаче выделяемых массивов в виде автоматических массивов подпрограммам неправильной формы? - PullRequest
0 голосов
/ 06 ноября 2018

Я компилирую следующую программу с gfortran -g -fcheck=all -Wall bug.F90:

program main
    implicit none

    real, dimension(:), allocatable :: arr

    allocate (arr(5))
    ! should fail, but happily writes out of bounds
    call foo(arr)

contains

subroutine foo(arr)
    real, dimension(10), intent(inout) :: arr

    arr(10) = 42
end subroutine

end program

При запуске программы она не завершается с ошибкой проверки границ во время выполнения. Почему это так? Это недостающая особенность gfortran или есть фундаментальная причина, почему это было бы плохой идеей?

Я понимаю, что существуют ситуации, когда может иметь смысл переосмысление массива с другой формой (и я предполагаю, что это разрешено в стандарте Фортрана), например, чтобы перейти от 2D-массива к уплощенному 1D-массиву, но в тех В этом случае количество элементов не изменится. Изменение в меньшем количестве элементов также может быть хорошо, но определенно не большее количество элементов, что и происходит выше.

РЕДАКТИРОВАТЬ: Чтобы продемонстрировать, что программа действительно записывает на недопустимые адреса памяти, я запустил ее с помощью инструмента electric fence :

$ LD_PRELOAD=libefence.so.0.0 ./a.out

  Electric Fence 2.2 Copyright (C) 1987-1999 Bruce Perens <bruce@perens.com>

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

Backtrace for this error:
#0  0x7f1f6e42b2da in ???
#1  0x7f1f6e42a503 in ???
#2  0x7f1f6e04ef1f in ???
#3  0x7f1f6ee00885 in foo
        at bug.F90:16
#4  0x7f1f6ee0099d in MAIN__
        at bug.F90:8
#5  0x7f1f6ee009df in main
        at bug.F90:8
Segmentation fault (core dumped)

Аналогично, запуск программы под valgrind дает:

==1162== Invalid write of size 4
==1162==    at 0x108885: foo.3498 (bug.F90:16)
==1162==    by 0x10899D: MAIN__ (bug.F90:8)
==1162==    by 0x1089DF: main (bug.F90:8)
==1162==  Address 0x5e05ae4 is 16 bytes after a block of size 20 alloc'd
==1162==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==1162==    by 0x108930: MAIN__ (bug.F90:6)
==1162==    by 0x1089DF: main (bug.F90:8)
...