在Eclipse中调试gfortran可执行文件时,全局数组/结构无法在gdb中访问 [英] Global arrays/structs not accessible in gdb while debugging gfortran executable in Eclipse

查看:352
本文介绍了在Eclipse中调试gfortran可执行文件时,全局数组/结构无法在gdb中访问的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我用gdb 7.11.1和gfortran 5.4.0来使用Eclipse(Neon.3版本4.6.3)来调试一个可执行文件,但只能看到本地的子程序变量和简单的

强>外部变量正确。考虑这个简化的例子:

  module ext_class 
type extstruct_type
integer(kind = 4),:: svar1
整数(kind = 4),:: svar2
结束类型extstruct_type
$ b $整数(kind = 4),save :: extvar
整数(kind = 4 ),dimension(4),save :: extarray
type(extstruct_type),save :: extstruct
end

module mod
子程序foo(invar)
使用ext_class,仅:extvar,extarray,extstruct
类型(real :: 8),intent(in):: invar
integer(kind = 4):: i
.. 。
!插入此处的调试器断点检查变量可见性
end
end



Eclipse的变量列表将正确显示局部变量( i )和输入( invar ),即使它们're modules / arrays,但任何外部/全局变量( extvar,extarray,extstruct )不会显示在名单。如果我尝试在表达式视图中手动输入它们,则会出现无法评估缺少符号的错误:


报告了多个错误。
$ b $ 1)无法执行MI命令:
-var-create - * extvar调试器后端的错误信息:
-var-create:无法创建变量对象

2)无法创建变量对象
$ b $ 3无法执行MI命令:
-data-evaluate-expression extvar来自调试器的错误信息后端:当前上下文中没有符号extvar。
$ b

4)执行MI命令失败:
-var-create - * extvar调试器后端的错误信息:
-var-create:无法创建变量对象

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

  nm< binaryname> | grep< modulename> 

然后我可以通过输入以下命令来查看gdb中的全局模块成员:

  print __< modulename> _MOD_< membername> 

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

  print __ext_class_MOD_extvar 
$ 1 = 0

对于一个整数的静态数组,它不适用仅打印第一个元素,从而阻止我查看任何成员数组的其他元素:

  print __ext_class_MOD_extarray 
$ 2 = 0
print __ext_class_MOD_extarray(1:4 )
无法对此类型执行子字符串

对于结构类型,它不正确只打印第一个成员 svar1 ),从而阻止我查看任何结构的其他成员:

  print __ext_class_MOD_extstruct 
$ 3 = 0
print __ext_class_MOD_extstruct%svar2
尝试提取非结构值的组件。

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

解决方案


<编辑:这个问题已经在一些版本中得到了解决(gfortran 6.2.0
在MacOS上使用gdb 7.12,但在Ubuntu的版本不同)。
在尝试以下步骤之前更新到最新版本。


我发现了一种兼容Eclipse的解决方法。看起来二进制文件没有跟踪关于变量类型的信息,只是他们在内存中的地址。所以可以通过将它们转换为适当的类型来查看变量。在Eclipse的表达式选项卡中输入 __ ext_class_MOD_extstruct ,然后右键单击条目并选择Cast to type ...,然后输入 extstruct_type !或者,只需输入

 (extstruct_type)__ ext_class_MOD_extstruct 

在表达式标签中。请注意,星号被省略(与C语法不同)。在gdb命令行中可以实现同样的效果,并且可以使用分隔符通过名称获得单个成员:



<$ p ((extstruct_type)(__ ext_class_MOD_extstruct)
$ 5 =(0,0)
print((extstruct_type)(__ ext_class_MOD_extstruct)%svar2
$ 6 = 0

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



<
打印__ext_class_MOD_extarray @ 4
$ 7 =(0,0,0,0)
打印__ext_class_MOD_extarray(2)
无法对此类型执行子字符串

请注意,在某些版本中访问单个数组元素仍然失败,希望他们解决此问题一次所有在新版本中。


I'm using Eclipse (Neon.3 Release 4.6.3) with gdb 7.11.1 and gfortran 5.4.0, to debug an executable, but it only seems possible to watch local subroutine variables and simple external variables properly. Consider this simplified example:

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's variable list will properly show the local variables (i) and the inputs (invar) even if they're modules/arrays, but any external/global variables (extvar, extarray, extstruct) don't show up in the list. If I try typing them manually into the "expressions" view, it gives errors about being unable to evaluate missing symbols:

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

I discovered the special notation used by the compiler to store these global variables in the binary executable using the command:

nm <binaryname> | grep <modulename>

I can then generally see the global module members in gdb by typing:

print __<modulename>_MOD_<membername>

However, it only works for simple member types in the module! For example I can see the integer member properly:

print __ext_class_MOD_extvar
$1 = 0

For a static array of integers, it improperly only prints the first element, thus preventing me from viewing any of the member array's other elements:

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

For a structure type, it improperly only prints the first member (svar1), thus preventing me from viewing any of the structure's other members:

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

I read here that this might actually be a problem with gfortran, not gdb, because it works fine when using Intel compilers. Is there possibly an extra flag I need to set when compiling? I already use -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.

I found a workaround that's also compatible in Eclipse. It seems that the binary isn't tracking information about the variable types, just their addresses in memory. So the variables can be viewed by casting them to the proper type. Enter __ext_class_MOD_extstruct into Eclipse's "expressions" tab and then right-click the entry and chose "Cast to type..." entering extstruct_type! Alternatively, simply enter

(extstruct_type)__ext_class_MOD_extstruct

in the "expression" tab. Note that asterisks are omitted (differing from the C syntax). The same can be achieved at the gdb command line and individual members are obtainable by name using the % delimiter:

print ((extstruct_type)(__ext_class_MOD_extstruct)
$5 = (0, 0)
print ((extstruct_type)(__ext_class_MOD_extstruct)%svar2
$6 = 0

Eclipse's "expression" option "Display as Array..." fails as it seems to be using C syntax pointer arithmetic (*) that isn't compatible with gdb for fortran, but it works when manually omitting the asterisks:

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

Note that accessing individual array elements still fails in some versions. Let's hope that they fix this issue once and for all in the newer releases.

这篇关于在Eclipse中调试gfortran可执行文件时,全局数组/结构无法在gdb中访问的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆