假设我有以下代码:
module eval_mod
implicit none(type, external)
private
public :: eval
abstract interface
real pure function real_function_t(x)
real, intent(in) :: x
end function
end interface
contains
pure function eval(f, x) result(res)
procedure(real_function_t) :: f
real, intent(in) :: x
real :: res
res = f(x)
end function
end module
program main
use iso_fortran_env, only: stdout => output_unit
use eval_mod, only: eval
implicit none(type, external)
write(stdout, *) eval(double, 2.)
write(stdout, *) eval(triple, 2.)
contains
pure real function double(x)
real, intent(in) :: x
double = 2. * x
end function
pure real function triple(x)
real, intent(in) :: x
triple = 3. * x
end function
end program
并用 gfortran -Wall -Wextra -Werror -g -fbounds-check
编译它。
如果我将断点设置为 eval_mod::eval
,我想查看调用了哪个函数参数 eval
。
我实际看到的是
Breakpoint 2, eval_mod::eval (f=0x7fffffffced8, x=2) at main.F90:17
如果我拿到地址然后关注this question ,我应该能够通过执行以下操作在符号表中看到函数名称:
info symbol 0x7fffffffced8
不幸的是我得到了一个错误
No symbol matches 0x7fffffffced8.
如何查看作为参数传递的函数的函数名称?
PS:我使用的是 gfortran 7.5.0 和 gdb 11.1。
最佳答案
double
和 triple
是内部函数(在主程序中)。由于来自父范围的变量的主机关联,传递内部函数很棘手。因此,它们通常使用蹦床来实现。您看到的地址是蹦床的地址,换句话说,就是所谓的 thunk。 trampoline 然后调用实际函数。
地址很可能指向堆栈中放置蹦床代码的某个位置。在该代码中,您可能会发现带有实际函数地址的跳转指令。
另请参阅 Steve Lionel 的这篇精彩文章 Doctor Fortran in “Think, Thank, Thunk”
关于Fortran 使用 gdb 从地址打印函数名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74047150/