将内部函数作为参数传递时出现分段错误 [英] Segmentation fault when passing internal function as argument
问题描述
我有一些代码将主程序的内部函数作为函数的参数传递:当最终调用传递的函数时,它将导致分段错误.仅当我将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/issues/286 >
WSL具有不可执行的堆栈.正在运行:
excestack -c test
在本机linux上,
要从二进制文件中删除execstack,将触发与我在WSL上相同的错误消息.在WSL上清除/设置execstack(使用-c/-s)不会执行任何操作.从github错误报告看来,它似乎不太可能得到解决.
I have some code that passes an internal function of the main program as an argument to a function: when the function that been passed is eventually called it causes a segmentation fault. This only occurs when I use Windows Subsystem for Linux (I'm using Ubuntu 16 on WSL); running on native Linux or Mac machines this does not occur.
A minimal example that crashes:
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
Compiled with:
gfortran-7 -ggdb test_fun_passing.f90 -o test
The backtrace, gdb output:
(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 ()
This one does work (moving f
into its own module but still passing as an argument) so it's something about f
being contained in the program.
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
Is passing f
in this way valid Fortran, or have I been relaying on some non-standard feature on native Linux?
Looks like I'm running into this:
https://github.com/Microsoft/WSL/issues/3083 and https://github.com/Microsoft/WSL/issues/286
WSL has a non-executable stack. Running:
excestack -c test
on native linux, to remove the execstack from the binary, triggers the same error message as I have on WSL. Clearing/setting the execstack (with -c/-s) on WSL does nothing. From the github bug report it seems its unlikely to be fixed.
这篇关于将内部函数作为参数传递时出现分段错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!