【问题标题】:How to print Fortran arrays in GDB?如何在 GDB 中打印 Fortran 数组?
【发布时间】:2016-10-14 20:50:48
【问题描述】:

在 C/C++ 中将指针打印为数组,我通常使用name@dimension。 Fortran 的等价物是什么?

【问题讨论】:

    标签: arrays fortran gdb


    【解决方案1】:

    Fortran 90 使用描述符来表示其数组的维度(形状)并传递假定形状的数组参数。 Fortran 中的指针也很特殊——它们只能指向合格的目标。这允许在 Fortran 中比在 C/C++ 中更好的调试器自省。只需使用print arr(index)info 命令之一 - 不需要花哨的东西。

    示例代码:

    program arr
      real, dimension(40) :: stack_array
      real, allocatable, dimension(:), target :: heap_array
      real, dimension(:), pointer :: ptr_array
      integer :: i
      ! Interface required because of the assumed-shape array argument
      interface
        subroutine foo(bar, baz, qux, ptr)
          real, dimension(:) :: bar
          real, dimension(40) :: baz
          real, dimension(*) :: qux
          real, dimension(:), pointer :: ptr
        end subroutine foo
      end interface
    
      allocate(heap_array(40))
    
      forall(i = 1:40) stack_array(i) = i
      heap_array = stack_array + 2
      ptr_array => heap_array
    
      print *, stack_array(1)
    
      call foo(stack_array, stack_array, stack_array, ptr_array)
    
      deallocate(heap_array)
    end program arr
    
    subroutine foo(bar, baz, qux, ptr)
      real, dimension(:) :: bar
      real, dimension(40) :: baz
      real, dimension(*) :: qux
      real, dimension(:), pointer :: ptr
    
      print *, bar(1), baz(1), qux(1), ptr(1)
    end subroutine foo
    

    使用调试信息编译并使用gdb运行:

    $ gfortran -g -o arr.x arr.f90 && gdb ./arr.x
    ...
    (gdb) info locals
    heap_array = (3, 4, 5, 6, 7, 8, 9, 10, 11, 12, ...
    ptr_array = (3, 4, 5, 6, 7, 8, 9, 10, 11, 12, ...
    stack_array = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ...
    (gdb) print heap_array
    $1 = (3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, ...
    (gdb) print ptr_array(3:7)
    $2 = (5, 6, 7, 8, 9)
    ...
    (gdb) info args
    bar = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, ...
    baz = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, ...
    qux = ()
    ptr = (3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, ...
    

    由于显而易见的原因,它无法显示假定大小的数组参数的内容,但您可以单独打印每个元素:

    (gdb) print qux(1)
    $5 = 1
    (gdb) print qux(2)
    $6 = 2
    (gdb) print qux(15)
    $7 = 15
    

    请注意,打印数组部分不适用于假定大小的数组参数,因为它们不是由描述符传递的,gdb 会遇到麻烦:

    (gdb) print qux(1:8)
    $8 = (0, 0, 0, 0, 0, 0, 2.25609053e-43, 0)
    (gdb) print qux(2:9)
    $9 = (0, 0, 0, 0, 0, 0, 2.25609053e-43, 0)
    

    【讨论】:

    • 这很好,但对我不起作用,你的 gdb/gfortran 版本是什么? (顺便说一句,您的子例程 foo 在示例中缺少一个参数)
    • gfortran 4.4.6(也使用 4.7.0 测试)和 gdb 7.2-50.e16 在 Scientific Linux 6.2 (RHEL 6.2) 上。您是否使用调试信息进行编译? (修正了缺失的论点 - 指出它的 10 倍)
    • 谢谢,我不知道这可能是某种错误。我使用 gfortran 4.7.1 和 gdb 7.4.1。如果我打印数组,我只会得到(0) 作为输出。
    • 可能您的 GDB 缺少 Fortran 支持。打破foo后,show languageThe current source language is "auto; currently fortran".
    【解决方案2】:

    我遇到了类似的问题,发现 thisthis 链接很有用。

    归结为:如果你没有正确的 gdb 和 gfortran 版本,你需要做的例子

    (gdb) print *((real *)my_array + 2)
    

    或(在我的情况下)

    (gdb) print *((real *)my_array + 2)   
    

    打印数组的第二个元素。你也可以这样做

    (gdb) print *((real_8 *)my_array + 2)@5
    

    查看数组元素 2, ... , 2+5。

    【讨论】:

    • *((datatype *)pointername ) 表示法有点令人困惑。如果使用( dtype *) ptrname 完成一次取消引用-嵌套一次如何导致*((dtype *) ptrname)??
    【解决方案3】:

    这在 gdb 7.7.1 中适用于我:

    print A(1)@N
    

    其中 A 是数组,N 是要打印的元素数。对于二维数组:

    print A(1,1)@N
    

    我知道这是一个老问题,但谷歌查询“gdb print fortran array”在此处引导。

    【讨论】:

      猜你喜欢
      • 2015-05-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-24
      • 1970-01-01
      • 2010-09-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多