将内部函数作为参数传递时的分割故障



我有一些代码,将主程序的内部函数作为参数传递给函数:当最终称为传递的函数时,它会导致分割故障。仅当我将Windows子系统用于Linux时(我在WSL上使用Ubuntu 16(才会发生。在本机Linux或MAC机器上运行,这不会发生。

崩溃的最小示例:

module test1
implicit none
contains
subroutine x(ff,y)
    interface 
        real function ff(y)
            real, intent(in) :: y
        end function ff
    end interface
    real, intent(in) :: y
    integer z
    z=ff(y)
end subroutine x
end module test1
program tester
use test1
implicit none
call x(f,1.0)
contains
real function f(y)
    real, intent(in) :: y
    write(*,*) y
    f=y*y
end function f
end program tester

编译:

 gfortran-7 -ggdb test_fun_passing.f90 -o test

回溯,GDB输出:

(gdb) bt                                                                                             
#0  0x00007ffffffde320 in ?? ()                                                                         
#1  0x0000000000400734 in test1::x (ff=0x7ffffffde320, y=1) at test_fun_passing.f90:17                  
#2  0x0000000000400829 in tester () at test_fun_passing.f90:31                                          
#3  0x0000000000400860 in main (argc=1, argv=0x7ffffffde64f) at test_fun_passing.f90:27                 
#4  0x00007ffffec70830 in __libc_start_main (main=0x40082c <main>, argc=1, argv=0x7ffffffde448,             init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7ffffffde438)        at ../csu/libc-start.c:291                                                                         
#5  0x0000000000400669 in _start ()                                                                     

这个确实有效(将f移动到自己的模块中,但仍作为参数传递(,因此它是关于f包含在程序中的东西。

module test1
implicit none
contains
subroutine x(ff,y)
    interface 
        real function ff(y)
            real, intent(in) :: y
        end function ff
    end interface
    real, intent(in) :: y
    integer z
    z=ff(y)
end subroutine x
end module test1
module test2
implicit none
contains
real function f(y)
    real, intent(in) :: y
    write(*,*) y
    f=y*y
end function f
end module test2
program tester
use test1
use test2
implicit none
call x(f,1.0)
end program tester

gfortran-7 -ggdb test_fun_passing.f90 -o test && ./test                                                                                              
1.00000000        

是以这种方式传递f有效fortran,还是我一直在本机Linux上的某些非标准功能中传递?

看起来我正在遇到这个:

https://github.com/microsoft/wsl/issues/3083和https://github.com/microsoft/wsl/wsl/issues/286

WSL具有不可执行的堆栈。跑步:

excestack -c test

在本机Linux上,要从二进制文件中删除Execstack,请触发与WSL上的错误消息相同的错误消息。WSL上的清除/设置execstack(带有-c/-s(什么都不做。从GitHub错误报告中,似乎不太可能被修复。

编辑:

似乎移至WSL版本2修复了此问题

最新更新