Fortran 使用 gdb 从地址打印函数名

标签 fortran gdb debug-symbols

假设我有以下代码:

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。

最佳答案

doubletriple内部函数(在主程序中)。由于来自父范围的变量的主机关联,传递内部函数很棘手。因此,它们通常使用蹦床来实现。您看到的地址是蹦床的地址,换句话说,就是所谓的 thunk。 trampoline 然后调用实际函数。

地址很可能指向堆栈中放置蹦床代码的某个位置。在该代码中,您可能会发现带有实际函数地址的跳转指令。

另请参阅 Steve Lionel 的这篇精彩文章 Doctor Fortran in “Think, Thank, Thunk”

关于Fortran 使用 gdb 从地址打印函数名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74047150/

相关文章:

cmake - 如何让 CMake 构建具有 MPI 支持的 Fortran 程序?

Fortran 格式的流读取带有新行的文件会导致问题

linux - GDB:lx-symbols 未定义命令

python - 如何在 Numpy 中使用 savetxt 有两个前导空格

fortran - 为什么在这个 openmp 代码中会发生段错误?

linux - 如何从Core Dump中提取EBP和ESP?

android-ndk - Windows 上的 ndk-gdb

c++ - 核心转储但 gdb 无法找到确切位置

macos - OS X Chrome的调试符号

c - 有没有办法在运行时访问调试符号?