Let's assume I have the following code:
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
and compile it with gfortran -Wall -Wextra -Werror -g -fbounds-check
.
If I set a breakpoint to eval_mod::eval
, I would like to see with which function argument eval
was called.
What I actually see is
Breakpoint 2, eval_mod::eval (f=0x7fffffffced8, x=2) at main.F90:17
If I take the address and follow this question, I should be able to see the function name in the symbol table by doing:
info symbol 0x7fffffffced8
Unfortunately I get an error
No symbol matches 0x7fffffffced8.
How can I see the function name of a function passed as argument?
PS: I use gfortran 7.5.0 and gdb 11.1.
double
and triple
are internal functions (inside the main program). Passing internal functions is tricky due to the host association of the variables from the parent scope. Therefore they are often implemented using trampolines. The address you see is the address of the trampoline, in other words, a so called thunk. The trampoline than calls the actual function.
The address most likely points somewhere on the stack where the trampoline code is placed. In that code you will likely find a jump instruction with the address of the actual function.
See also this great article by Steve Lionel Doctor Fortran in “Think, Thank, Thunk”