This is the mail archive of the fortran@gcc.gnu.org mailing list for the GNU Fortran project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: passing wrong type of agrument corrupts unrelated data


On 7/28/2011 10:08 AM, Anton Shterenlikht wrote:
I came across this accidentally.
Maybe I'm just overheating.

I'm calling a lapack routine
from my code, and after exit
from that lapack routine, an
unrelated array is corrupted.
This happens because I pass
it integer arrays instead of
double precision.

I know I should use interface block
to avoid this in the first place.
HOwever, I expected to get a segfault
in a situation like this.


$ cat z.f90 program z

  implicit none
  double precision :: c(6,6),comp(6,6)

INTEGER :: I,J,IPIV(6),INFO, WORK(6),CHECK(6,6)


C=0.0d0 FORALL(I=1:6) C(I,I)=1.0d0 FORALL(I=1:3) C(I,1:3) = C(I,1:3) + 2.0d0


COMP = C


      WRITE(*,*) "Comp"
      WRITE(*,'(6ES15.7)') (Comp(I,:), I=1,6)

! http://www.netlib.org/lapack/double/dgetrf.f

CALL DGETRF(6,6,COMP,6,IPIV,INFO)

      WRITE(*,*) "C before dgetri"
      WRITE(*,'(6ES15.7)') (C(I,:), I=1,6)

! http://www.netlib.org/lapack/double/dgetri.f

CALL DGETRI(6,COMP,6,IPIV,WORK,6,INFO)

      WRITE(*,*) "C after dgetri"
      WRITE(*,'(6ES15.7)') (C(I,:), I=1,6)

end program z

$ ./a.out
  Comp
   3.0000000E+00  2.0000000E+00  2.0000000E+00  0.0000000E+00  0.0000000E+00  0.0000000E+00
   2.0000000E+00  3.0000000E+00  2.0000000E+00  0.0000000E+00  0.0000000E+00  0.0000000E+00
   2.0000000E+00  2.0000000E+00  3.0000000E+00  0.0000000E+00  0.0000000E+00  0.0000000E+00
   0.0000000E+00  0.0000000E+00  0.0000000E+00  1.0000000E+00  0.0000000E+00  0.0000000E+00
   0.0000000E+00  0.0000000E+00  0.0000000E+00  0.0000000E+00  1.0000000E+00  0.0000000E+00
   0.0000000E+00  0.0000000E+00  0.0000000E+00  0.0000000E+00  0.0000000E+00  1.0000000E+00
  C before dgetri
   3.0000000E+00  2.0000000E+00  2.0000000E+00  0.0000000E+00  0.0000000E+00  0.0000000E+00
   2.0000000E+00  3.0000000E+00  2.0000000E+00  0.0000000E+00  0.0000000E+00  0.0000000E+00
   2.0000000E+00  2.0000000E+00  3.0000000E+00  0.0000000E+00  0.0000000E+00  0.0000000E+00
   0.0000000E+00  0.0000000E+00  0.0000000E+00  1.0000000E+00  0.0000000E+00  0.0000000E+00
   0.0000000E+00  0.0000000E+00  0.0000000E+00  0.0000000E+00  1.0000000E+00  0.0000000E+00
   0.0000000E+00  0.0000000E+00  0.0000000E+00  0.0000000E+00  0.0000000E+00  1.0000000E+00
  C after dgetri
   3.0000000E+00  2.0000000E+00  2.0000000E+00  0.0000000E+00  0.0000000E+00  7.1428571E-01
   2.0000000E+00  3.0000000E+00  2.0000000E+00  0.0000000E+00  0.0000000E+00 -2.8571429E-01
   2.0000000E+00  2.0000000E+00  3.0000000E+00  0.0000000E+00  0.0000000E+00 -2.8571429E-01
   0.0000000E+00  0.0000000E+00  0.0000000E+00  1.0000000E+00  0.0000000E+00  0.0000000E+00
   0.0000000E+00  0.0000000E+00  0.0000000E+00  0.0000000E+00  1.0000000E+00  0.0000000E+00
   0.0000000E+00  0.0000000E+00  0.0000000E+00  0.0000000E+00  0.0000000E+00  0.0000000E+00

Note that 3 values of array C have
become corrupted after a call to
dgetri, even though array C is
not part of the arguments to this
routine.

This is with 4.1.2 20080704 on Linux 2.6.18-194.32.1.el5 #1 SMP x86_64


However, when I compile and link the same code on my FreeBSD box: FreeBSD 9.0-CURRENT #3 r221488 ia64

I get:


% gfortran45 -llapack -lblas z.f90 % ./a.out Comp 3.0000000E+00 2.0000000E+00 2.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00 2.0000000E+00 3.0000000E+00 2.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00 2.0000000E+00 2.0000000E+00 3.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00 1.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00 1.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00 1.0000000E+00 C before dgetri 3.0000000E+00 2.0000000E+00 2.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00 2.0000000E+00 3.0000000E+00 2.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00 2.0000000E+00 2.0000000E+00 3.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00 1.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00 1.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00 1.0000000E+00 C after dgetri 3.0000000E+00 2.0000000E+00 2.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00 2.0000000E+00 3.0000000E+00 2.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00 2.0000000E+00 2.0000000E+00 3.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00 1.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00 1.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00 1.0000000E+00

in other words, here passing wrong type
arguments to dgerti didn't corrupt and
unrelated array C.


When you store data beyond the end of an array, unless that array over-run is within a sequence type (including COMMON), there is no control over what is over-written, or whether it results in a segv.
I certainly hope you don't depend on segv as a substitute for subscript range checks.


--
Tim Prince


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]