Howto use gdb to print FORTRAN arrays in mixed language code

333 views
Skip to first unread message

jimp...@mail.utexas.edu

unread,
Aug 13, 2006, 11:38:09 AM8/13/06
to gg95
Debugging support has significantly improved over time for g95, but for
those of us trying to debug mixed language code, often the solution is
to resort to lots of WRITE statements, because the command
(gdb) p y
where y is an array yields the array descriptor rather than values in
the array
(gdb) p y
$1 = {offset = 0xfefff630 "??\005\b\024", rank = 1, esize = 8,
base = 0xfefff638, info = {8, 1, 4}}
(gdb)

Note: the above command works as expected, printing the N values of y,
if only FORTRAN code is used.

The problem is deciphering the array descriptor and getting at the
actual array values. A problem that many forums just say is "not
trivial" but don't give any advice or examples that might work. Since
I'm going to assume that most people working with FORTRAN are doing so
for numerical work and therefore their arrays are arrays of numbers (as
opposed to some other abstract object). Then the following will work
for most arrays (either local or arguments passed to a
subroutine/function)

For real single precision arrays:
real(kind=1.e0), intent (in | out | inout) :: y(4)
(gdb) x/f y.base+(y.esize* (n-1) )
prints the value of the array index n (using FORTRAN numbering
convention of 1...n)

For real double precision arrays:
real(kind=1.d0), intent (in | out | inout) :: y(4)
(gdb) x/fg y.base+(y.esize*(n-1) )
--The only difference is the need to use the 'g' size specifier in
formatting the output

see 'help x' under gdb for the various combinations of formats and size
specifiers.

This is not a complete solution however, because a local array variable
whose size is dependent upon another array will not work with this
method.

real, intent(in) :: v(:)
real :: x(4)
real :: y(size(v))

The above method will work for v and x, but not y

The difference, I'm guessing, is how the compiler defines the array
descriptor, since it can't place a value in the .esize field, the value
must be a pointer of some sort to the original array's .esize.
However, any attempts to dereference that pointer by me have been
unsuccessful. If anyone can help me with this last bit, I'd be very
appreciative.

BTW, if you would like a script to save some typing in gdb, this
offered as is:

define p_ary
if ($arg0.esize == 8)
x/fg $arg0.base+(8*($arg1-1) )
end
if ($arg0.esize == 4)
x/f $arg0.base+(4*($arg1 -1) )
end
end

document p_ary
Prints the contents of Fortran double or single precision arrays.
Usage: p_ary <array name> <index>
end

Andy

unread,
Aug 31, 2006, 2:32:51 PM8/31/06
to gg95
If the array is contiguous, which is most arrays are, the 'base' member
points to a block of memory where the values are actually stored. So
something like:

(gdb) x /10fg y.offset

would print 10 double precision reals in the y() array. I do
occasionally correspond with a guy who is working on better gdb support
for g95.

Andy

Reply all
Reply to author
Forward
0 new messages