首页 > 代码库 > How to debug Fortran programs using gdb

How to debug Fortran programs using gdb

<style></style>

Previously, I thought the debugging functionality provided by gdb for Fortran program was quite limited due to experiences of a couple of failed attempts to print allocatable arrays. However, having given several another tries today, I discovered that gdb does support printing values of allocatable arrays, although it may be a little inconvenient. Now, let‘s see the details:

We have the test code as follows, in which a derived type cmp, an allocatable array a and a static array b are defined.

 program test   implicit none   type cmp      integer a      integer b      integer, dimension(:), allocatable :: c      integer, dimension(5) :: d   end type cmp   integer, dimension(:), allocatable :: a   integer, dimension(5) :: b = (/1,2,3,4,5/)   type(cmp) x   allocate(a(5))   allocate(x%c(5))   a = (/1,2,3,4,5/)   x%a = 5   x%b = 10   x%c = a   x%d = a   write(STDOUT,*), a   write(STDOUT,*), b   write(STDOUT,*), x%c   deallocate(a)   deallocate(x%c) end program test

For the static array b, there is no need to mention it because gdb has a good support whether or not it is defined inside a derived type. However, if we want to directly print the allocatable array in gdb, a null value 0 will be printed:

(gdb) p a$1 = (0)

If we treat the allocatable array as a C pointer,

(gdb) p *aAttempt to take contents of a non-pointer value.(gdb) p a(1)$2 = 0 # Note: this is a wrong value(gdb) p a[1]A syntax error in expression, near `[1]‘. # Note: square brackets are invalid

The correct form is:

(gdb) p *((integer *)a)$3 = 1(gdb) p *((integer *)a+1)$4 = 2# ... and so on.

The whole array can also be printed out all at once:

(gdb) p *((integer *)a)@5$5 = (1, 2, 3, 4, 5)

For the allocatable array in the derived type cmp, we should note that the member variable along with its parent should be wrapped in brackets:

(gdb) p *((integer *)x%c)Attempt to extract a component of a value that is not a structure. # wrong(gdb) p *((integer *)(x%c))$1 = 1 # right(gdb) p *((integer *)(x%c)+1)$2 = 2(gdb) p *((integer *)(x%c))@5$3 = (1, 2, 3, 4, 5)

OK, up to now, our Fortran program can be debugged efficiently, without having to insert debugging print or write subroutine any more!