在 Eclipse 中调试 gfortran 可执行文件时,在 gdb 中无法访问全局 arrays/structs

Global arrays/structs not accessible in gdb while debugging gfortran executable in Eclipse

我正在使用带有 gdb 7.11.1 和 gfortran 5.4.0 的 Eclipse(Neon.3 版本 4.6.3)来调试可执行文件,但似乎只能观察本地子例程变量和 simple 外部变量正常。考虑这个简化的例子:

module ext_class
  type extstruct_type
    integer(kind=4),          ::svar1
    integer(kind=4),          ::svar2
  end type extstruct_type

  integer(kind=4),               save :: extvar
  integer(kind=4), dimension(4), save :: extarray
  type (extstruct_type),         save :: extstruct
end

module mod
  subroutine foo(invar)
    use ext_class,          only : extvar, extarray, extstruct
    type (real::8), intent(in)  :: invar
    integer(kind=4)             :: i
    ...
    !Debugger breakpoint inserted here to check variable visibility
  end
end

Eclipse 的变量列表将正确显示局部变量 (i) 和输入 (invar),即使它们是 modules/arrays,但任何 external/global 变量(extvar, extarray, extstruct) 没有出现在列表中。如果我尝试将它们手动输入到 "expressions" 视图中,它会给出有关无法评估缺失符号的错误:

Multiple errors reported.

1) Failed to execute MI command: -var-create - * extvar Error message from debugger back end: -var-create: unable to create variable object

2) Unable to create variable object

3) Failed to execute MI command: -data-evaluate-expression extvar Error message from debugger back end: No symbol "extvar" in current context.

4) Failed to execute MI command: -var-create - * extvar Error message from debugger back end: -var-create: unable to create variable object

我发现编译器使用特殊符号将这些全局变量存储在二进制可执行文件中,使用命令:

nm <binaryname> | grep <modulename>

然后我通常可以通过键入以下内容在 gdb 中查看全局模块成员:

print __<modulename>_MOD_<membername>

但是,它只适用于模块中的简单成员类型!例如,我可以正确地看到整数成员:

print __ext_class_MOD_extvar
 = 0

对于静态整数数组,它不正确地只打印第一个元素,因此我无法查看任何成员数组的其他元素:

print __ext_class_MOD_extarray
 = 0
print __ext_class_MOD_extarray(1:4)
Cannot perform substring on this type

对于结构类型,它不正确地只打印第一个成员 (svar1),因此我无法查看该结构的任何其他成员:

print __ext_class_MOD_extstruct
 = 0
print __ext_class_MOD_extstruct%svar2
Attempt to extract a component of a value that is not a structure.

我读到 here 这实际上可能是 gfortran 的问题,而不是 gdb,因为它在使用 Intel 编译器时工作正常。编译时我可能需要设置一个额外的标志吗?我已经使用 -g -O0

EDIT: This issue has been resolved in some versions (gfortran 6.2.0 with gdb 7.12 on MacOS, but not on the same versions in Ubuntu). Update to the latest version before trying the steps below.

我找到了一种在 Eclipse 中也兼容的解决方法。似乎二进制文件没有跟踪有关变量类型的信息,只是它们在内存中的地址。因此可以通过将变量转换为正确的类型来查看变量。在 Eclipse 的 "expressions" 选项卡中输入 __ext_class_MOD_extstruct 然后右键单击该条目并选择 "Cast to type..." 输入 extstruct_type!或者,只需输入

(extstruct_type)__ext_class_MOD_extstruct

在 "expression" 选项卡中。请注意星号被省略(与 C 语法不同)。同样可以在 gdb 命令行上实现,并且可以使用 % 分隔符按名称获取各个成员:

print ((extstruct_type)(__ext_class_MOD_extstruct)
 = (0, 0)
print ((extstruct_type)(__ext_class_MOD_extstruct)%svar2
 = 0

Eclipse 的 "expression" 选项 "Display as Array..." 失败,因为它似乎使用与 fortran 的 gdb 不兼容的 C 语法指针算法 (*),但它在手动时工作省略星号:

print __ext_class_MOD_extarray@4
 = (0, 0, 0, 0)
print __ext_class_MOD_extarray(2)
Cannot perform substring on this type

请注意,在某些版本中访问单个数组元素仍然会失败。我们希望他们在较新的版本中一劳永逸地解决这个问题。