Fortran print allocatable array in gdb

2020-01-26 11:28发布

问题:

I'm adding some functionality on to an open-source scientific code. I work with a lot of allocatables, but I'm having some trouble printing them properly. For example, I declare and allocate, and then use:

real(dp), allocatable :: psi_n_phi(:)
! some other stuff here
allocate(psi_n_phi(1:fock_info%nocc(isp)))
! nocc(isp) is simply equal to 1 in this context
! some other stuff here
do n = 1, fock_info%nocc(isp)
    psi_n_phi(n) = dot_product(fock_info%psi(:, n, isp), p)
enddo

I later get an array mismatch and I am using gdb to figure out why. If I print:

(gdb) p psi_n_phi 
$23 = (0)

But this clearly is not the case, as evidenced by:

(gdb) p psi_n_phi@1
$25 = (( 0) )
(gdb) p psi_n_phi@2
$26 = (( 0) ( 0) )
(gdb) p psi_n_phi@10
$28 = (( 0) ( 0) ( 0) ( 2.0162819006781271e-320) ( 2.2600760244771319e-316) ( 2.3792209431030402e-316) ( 6.9179818424594845e-310) ( 2.2598704931684619e-316) ( 6.9179818424672413e-310) ( 0) )

I got the information about using the @ notation from http://numericalnoob.blogspot.co.il/2012/08/fortran-allocatable-arrays-and-pointers.html. This is just about the only source I can find on the issue, although I have seen some other questions where people run into similar issues (but none of them were able to fix it).

Any ideas here? I would like to understand why printing it just comes out as ((0)), and how I can get it to print like a normal array.

回答1:

Use

(gdb) print *((real *)A+m)@n

where A is the array, m is the shift in the position (no need to write +m in the case m=0) and n is the number of elements that you want to print. If you're working with double precision reals then replace real by real_8. Also, for integers replace real by int, and for long integers use long_int. Credit goes to http://numericalnoob.blogspot.fr/2012/08/fortran-allocatable-arrays-and-pointers.html



回答2:

UPDATE: Works out-of-the-box in Ubuntu 16.04 LTS

The issue is being discussed for almost a decade already (e.g. https://sourceware.org/bugzilla/show_bug.cgi?id=9395) and is partially fixed in some distros. I have reported the same problem in gdb that comes with Ubuntu 14.04 LTS. The workaround was in a similar fashion as Francois Jacq suggested here, but without damaging dpkg-controlled directories.

I have used alien tool from native Ubuntu repo to convert a gdb RPM from Fedora (namely GNU gdb (GDB) Fedora 7.9-10.fc23) into .deb package, and then used dpkg to install it. Now i have installed gdb-7.9.1-7.1.x86_64.rpm from OpenSUSE in a similar manner:

fakeroot alien gdb-7.9.1-7.1.x86_64.rpm
sudo dpkg -i gdb_7.9.1-8.1_amd64.deb

In many cases it works correctly with simple pointers and allocatable arrays. Though segfaults of gdb are often when trying to touch large and/or complex structures. Probably, that is why many maintainers prefer not to include the fortran patch into mainstream...

Please consider confirming the bug in your distro bug trackers, so maintainers will pay more attention to it.



回答3:

Unfortunately GDB trunk comes with no support of allocatable arrays. But the Archer branch includes some support.

I recently read the following post of Tobias Burnus :

https://gcc.gnu.org/ml/fortran/2012-09/msg00013.html

I work with Ubuntu 14.02. I downloaded the most recent OpenSUSE rpm package of gdb and extracted it by a command like

rpm2cpio myrpmfile.rpm | cpio -idmv

Then I copied the gdb executable program in /usr/local/bin (with sudo cp) and I was happy to see it working correctly !