如何用GDB查看Fortran中作为参数传递的函数名称?
Fortran过程参数调试:查看传递的函数名称
问题场景
现有如下Fortran代码:
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处设置断点后,查看传入的函数参数f时仅能看到内存地址(如f=0x7fffffffced8),执行info symbol 0x7fffffffced8时提示No symbol matches 0x7fffffffced8,无法获取对应的函数名称。使用环境为gfortran 7.5.0、gdb 11.1。
解决方法
- 升级gfortran版本:gfortran 7.x系列对Fortran过程指针的调试信息生成支持不完善,升级到9.x及以上版本后,编译时保留
-g选项,gdb可直接识别过程指针对应的函数名称,无需额外操作。 - 添加编译选项
-fno-omit-frame-pointer:针对老版本编译器,添加该选项可避免优化掉栈帧相关的调试信息,帮助gdb解析函数地址对应的符号,编译命令改为:gfortran -Wall -Wextra -Werror -g -fbounds-check -fno-omit-frame-pointer - 使用gdb的Fortran过程指针打印:若已升级到较新版本gdb,直接执行
print f即可显示函数名称;针对老gdb,可尝试将指针强制转换为通用函数指针后查询:p (void(*)())f info symbol <输出的地址> - 代码层面的临时 workaround:若无法升级工具链,可在代码中添加调试辅助逻辑,比如给抽象接口增加返回函数名称的方法,或在调用
eval时额外传递函数名字符串参数,手动输出或查看标识。
内容的提问来源于stack exchange,提问作者mcocdawc
相关产品推荐
相关产品推荐

