falconskull
falconskull

Reputation: 303

Confusing debugging error in Fortran program

I've been sitting here for a while quite baffled as to why my debugger keeps displaying an error in my code when the program runs fine. There are three parts to a very simple program that is just reading in information from a file.

My code is broken into three Fortran files given below and compiled via

ifort -o test global.f90 read.f90 test.f90

global.f90:

module global
  implicit none
  integer(4), parameter :: jsz = 904
end module global

read.f90:

subroutine read(kp,q,wt,swt)
implicit none
integer(4) :: i, j
integer(4), intent(in) :: kp
real(8), intent(out) :: swt, q(kp,3), wt(kp)
swt = 0.0d0; q(:,:) = 0.0d0; wt(:) = 0.0d0
open(7,file='test.dat')
read(7,*) ! Skipping a line
do i = 1, kp
  read(7,1000)(q(i,j),j=1,3), wt(i)
  swt = swt + wt(i)
end do
close(7)
return
1000 format(3F10.6,1X,1F10.6)
end subroutine read

test.f90:

program test
use global
integer(4) :: i, j
real(8) :: tot, qq(jsz,3), wts(jsz)
call read(jsz,qq,wts,tot)
stop
end program test

The error I keep receiving is

Breakpoint 1, read (kp=904, 
q=<error reading variable: Cannot access memory at address 0x69bb80>,
wt=..., swt=6.9531436082559572e-310) at read.f90:6

This error appears right when the subroutine of read is called. In other words, I'm adding a breakpoint at the read subroutine and running the code in gdb after the breakpoint is added. The program will continue to run as expected and give the correct outputs when I include write statements in the 'test' program. However, if I use the gdb print options I receive an error of 'Cannot access memory at address 0x69bb80' for array q only. All other arrays and variables can be displayed with no problems.

As I would like the read subroutine to be a stand alone subroutine and not necessarily use any global parameters, I have not used the global module and instead called the variable kp into the subroutine. I decided to test whether using the global module would help, and if I use jsz in place of kp, I do indeed remove the error. However, since this isn't my overall goal with the subroutine, I would hopefully like to figure out how to fix this without the use of the global module. (I also tried not using the global at all and setting the parameter variable of kp in the test.f90 program directly, but this also gives the error.)

Any insight on possible reasons for this error, or suggestions to try and fix the memory addressing issue would be greatly appreciated.

Upvotes: 1

Views: 2097

Answers (2)

taerath
taerath

Reputation: 85

I think this is an issue specific to the ifort+gdb combination that is fixed with newer gdb versions. Here's a smaller example to reproduce the issue:

$ cat test.f90 
  subroutine bar(arg)
    integer, intent(inout):: arg

    print *, 'bar argument is', arg
    arg = 42
  end subroutine bar

  program test
    integer:: param
    param = 3
    call bar(param)
    print *, 'post-bar param:', param
  end program test
$ ifort -g -O0 -o test test.f90
$ gdb --quiet test
Reading symbols from /home/nrath/tmp/test...done.
(gdb) b 4
Breakpoint 1 at 0x402bd0: file test.f90, line 4.
(gdb) r
Starting program: /home/nrath/tmp/test 
[Thread debugging using libthread_db enabled]

Breakpoint 1, bar (arg=@0x2aaa00000003) at test.f90:4
4       print *, 'bar argument is', arg
(gdb) p arg
$1 = (REF TO -> ( INTEGER(4) )) @0x2aaa00000003: <error reading variable>
(gdb) quit
$ gdb --version | head -1
GNU gdb (GDB) Red Hat Enterprise Linux (7.2-60.el6_4.1)

However, if you compile with gfortran instead of ifort, or if you use GDB 7.7.1, it works fine.

Upvotes: 1

Mz_Chen
Mz_Chen

Reputation: 87

Did you add the INTERFACE statement to the end of your programme? You need it when you call a function that is not contained in the programme.

Upvotes: 0

Related Questions