Search code examples
fortrangdbdebug-symbols

Fortran use gdb to print function name from address


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.


Solution

  • 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”