【问题标题】:Segmentation fault (code dumped) error in gfortrangfortran 中的分段错误(代码转储)错误
【发布时间】:2021-02-22 21:30:39
【问题描述】:

我正在比较两个文件并使用 Fortran 查找并置点。代码在我的带有 gfortran 版本 10.2.0 的笔记本电脑上运行良好,而我将此代码保存在我的 ssh 服务器上(ssh 使用 gfortran 4.8.5;也尝试使用版本 8.3.1),它适用于大多数迭代,但提供几次迭代出现以下错误:

Program received signal SIGSEGV: Segmentation fault - invalid memory reference.

Backtrace for this error:
#0  0x7F750B7F8697
#1  0x7F750B7F8CDE
#2  0x7F750ACF33FF
#3  0x402493 in MAIN__ at 1_myd_trmm_coloc.f90:?
1a_myd_trmm_coloc.sh: line 10: 42668 Segmentation fault  (core dumped) ./1_myd_trmm_coloc.out < infile

以下是我的 Fortran 代码:

    IMPLICIT NONE
    Character*180::mydf,trmmf,outf
    integer::my,mmn,md,mh,mmi,ms,mat
    real::mla,mlo,ma412,ma470,ma550,ma660,mae
    integer::ty,tmn,td,th,ic,i,j,i1,j1,i22,j22,n
    real::tla,tlo,tpr

    real,allocatable::m(:,:),t(:,:)
    real::delat,delon,c,a,dist,rlon1,rlon2,rlat1,rlat2
    real::mtim,ttim,maxttim,minttim,minlat,maxlat,minlon,maxlon

    real,dimension(100000)::ds,ala,alo
    integer,dimension(100000)::ay,amn,ad,ah,ami,as,aat
    real,dimension(100000)::a412,a470,a550,a660,aae,ppr

    read*,mydf
    read*,trmmf
    read*,outf

    open(11,file=mydf,status='old')
        i=0
 5      read(11,*,end=90,err=80)my,mmn,md,mh,mmi,ms,mla,mlo, &
             ma412,ma470,ma550,ma660,mae,mat
        i=i+1
 80     goto 5
 90     close(11)
            allocate(m(i,14))
        open(11,file=mydf,status='old')
        i1=0
  6     read(11,*,end=91,err=81)my,mmn,md,mh,mmi,ms,mla,mlo, &
            ma412,ma470,ma550,ma660,mae,mat
        i1=i1+1
            m(i1,1)=my ; m(i1,2)=mmn ; m(i1,3)=md
            m(i1,4)=mh ; m(i1,5)=mmi ; m(i1,6)=ms
            m(i1,7)=mla ; m(i1,8)=mlo ; m(i1,9)=ma412
            m(i1,10)=ma470 ; m(i1,11)=ma550 ; m(i1,12)=ma660
            m(i1,13)=mae ; m(i1,14)=mat
  81        goto 6
  91    close(11)

    open(12,file=trmmf,status='old')
        j=0
  15        read(12,*,end=190,err=180)ty,tmn,td,th,tla,tlo,tpr
        j=j+1
  180       go to 15
  190   close(12)
            allocate(t(j,7))
    open(12,file=trmmf,status='old')
        j1=0
  16        read(12,*,end=191,err=181)ty,tmn,td,th,tla,tlo,tpr
        j1=j1+1
            t(j1,1)=ty ; t(j1,2)=tmn ; t(j1,3)=td
            t(j1,4)=th ; t(j1,5)=tla ; t(j1,6)=tlo
            t(j1,7)=tpr ;
  181       go to 16
  191   close(12)

    open(51,file=outf,status='unknown')

    do  i22=1,i
                n=0;    ds=-999.0
                ala=-999.0;alo=-999.0;a412=-999.0;a470=-999.0
                a550=-999.0;a660=-999.0;aae=-999.0;aat=-999;
                ppr=-999.0;
                ic=0
        do j22=1,j
            if(t(j22,1).eq.m(i22,1).and.t(j22,2).eq.m(i22,2).and. &
                    t(j22,3).eq.m(i22,3)) then
                    minlat=t(j22,5)-0.125; maxlat=t(j22,5)+0.125
                    minlon=t(j22,6)-0.125; maxlon=t(j22,6)+0.125
                    mtim=m(j22,4)+(m(j22,5)/60)+(m(j22,6)/3600)
                    ttim=t(j22,4)
                    minttim=ttim-0.5; maxttim=ttim+0.5

                if(m(i22,7).ge.minlat.and.m(i22,7).le.maxlat.and. &
                   m(i22,8).ge.minlon.and.m(i22,8).le.maxlon.and. &
                     mtim.ge.minttim.and.mtim.le.maxttim) then

                        rlat1=(m(i22,7)*3.141592657)/180.0; rlat2=(t(j22,5)*3.141592657)/180.0
                        rlon1=(m(i22,8)*3.141592657)/180.0; rlon2=(t(j22,6)*3.141592657)/180.0
                        delat=rlat2-rlat1; delon=rlon2-rlon1
                        a=SIN(delat/2.0)**2+(COS(rlat1)*COS(rlat2)*SIN(delon/2.0)**2)
                        c=2.0*atan2(sqrt(a),sqrt(1-a))
                        dist=6378136.300*c
                        ic=ic+1
                        ! print*,ic
                        ds(ic)=dist
                        ala(ic)=m(i22,7)
                        alo(ic)=m(i22,8)
                        ay(ic)=m(i22,1); amn(ic)=m(i22,2); ad(ic)=m(i22,3)
                        ah(ic)=m(i22,4); ami(ic)=m(i22,5); as(ic)=m(i22,6)
                        a412(ic)=m(i22,9); a470(ic)=m(i22,10)
                        a550(ic)=m(i22,11); a660(ic)=m(i22,12)
                        aae(ic)=m(i22,13); aat(ic)=m(i22,14)
                        ! py(ic)=t(j22,1); pmn(ic)=t(j22,2); pd(ic)=t(j22,3)
                        ! ph(ic)=t(j22,4); pla(ic)=t(j22,5); plo(ic)=t(j22,6)
                        ppr(ic)=t(j22,7)
                    end if
            end if
        end do
        if (ic>0)then
            write(51,111)minval(ds,ds.ne.-999.0), ay(minloc(ds,ds.ne.-999.0)),  &
                amn(minloc(ds,ds.ne.-999.0)), ad(minloc(ds,ds.ne.-999.0)),      &
                ah(minloc(ds,ds.ne.-999.0)), ami(minloc(ds,ds.ne.-999.0)),      &
                as(minloc(ds,ds.ne.-999.0)), ala(minloc(ds,ds.ne.-999.0)),      &
                alo(minloc(ds,ds.ne.-999.0)), a412(minloc(ds,ds.ne.-999.0)),    &
                a470(minloc(ds,ds.ne.-999.0)), a550(minloc(ds,ds.ne.-999.0)),   &
                a660(minloc(ds,ds.ne.-999.0)), aae(minloc(ds,ds.ne.-999.0)),    &
                aat(minloc(ds,ds.ne.-999)), ppr(minloc(ds,ds.ne.-999.0))
            n=n+1
            ! print*,n
        end if
        end do
  111           format(f16.6,1x,i4,1x,5(1x,i2.2),1x,2(1x,f8.3),1x,5(1x,f6.3),1x,i2,1x,f8.3)
            deallocate(m)
            deallocate(t)
        close(51)
  end

我正在寻找代码中的错误。 以下是示例数据文件:

文件-1

    2008  04 06 09 27 03    10.250   50.250    0.303    0.303    0.303    0.303    0.000   1
    2008  04 06 09 27 03    10.500   50.500    0.247    0.247    0.247    0.247    0.000   1
    2008  04 06 09 27 03    10.750   50.500    0.219    0.180    0.142    0.111    1.500   2
    2008  04 06 09 27 03    11.000   50.500    0.157    0.129    0.102    0.079    1.500   2
    2008  04 06 09 27 46    11.250   50.000    0.064    0.053    0.042    0.032    1.500   2
    2008  04 06 09 27 46    11.250   50.250    0.151    0.124    0.098    0.076    1.500   2
    2008  04 06 09 27 46    11.500   50.250    0.129    0.106    0.083    0.065    1.500   2

文件-2

    2008 4 6 6 9.875 29.125 0
    2008 4 6 6 10.125 29.125 0
    2008 4 6 6 10.375 29.125 0
    2008 4 6 6 10.625 29.125 0
    2008 4 6 6 10.875 29.125 0
    2008 4 6 6 11.125 29.125 0
    2008 4 6 6 11.375 29.125 0
    2008 4 6 6 11.625 29.125 0
    2008 4 6 6 11.875 29.125 0
    2008 4 6 6 12.125 29.125 0

【问题讨论】:

  • 对于所有 Fortran 问题,请使用标签 fortran。使用 gfortran 时,使用标志 -g -Wall -fcheck=all 编译代码以获得更有用的回溯并检查某些编码错误。我在您的代码中看不到任何 IMPLICIT NONE。将它用于您的所有代码,并在每次要求其他人检查您的代码时使用它。这非常重要。
  • 感谢您的回复。我做了-g -Wall -fcheck=all 来获取回溯,但它没有任何警告。正如我所说,代码非常适合高于 5.x 的 gfortran 版本,但它只会在 gfortran 4.8 版本的几次迭代中产生问题。我忘记在此处添加IMPLICIT NONE。谢谢你的指出。
  • 所以,不要使用早于 5.x 的版本!对编译器进行了数千次更改和修复。或者,用你的头撞你的桌子。
  • 如果 gfortran-10.2 可用,我认为尝试“-Wall -Wextra”选项可能很有用(这给了我很多警告,如实数与实数比较、实数与整数赋值)用于堆栈等的大型数组等)
  • 重点是你应该在这里发布更好的回溯。请edit您的问题并插入。但是,我同意您应该使用更新的 GCC 版本。请注意,您始终可以在主目录中安装自己的 gcc。

标签: ubuntu fortran fortran90


【解决方案1】:

我没有该版本可供测试,但我怀疑您的问题源于 aat(minloc(ds,ds.ne.-999)) - 您正在针对整数 -999 测试真正的 ds,这很少是好主意。此外(仅供参考,在实数中测试 eq 仅在少数情况下可靠。

注意发布示例数据集将有助于进一步诊断

【讨论】:

  • 根据 Fortran 的规则,有理表达式是可以的。从 Fortran 2018, 10.1.5.5.1 开始: 在数值关系运算 x1 rel-op x2 中,如果 x1 和 x2 的类型或 kind 类型参数不同,则将它们的值转换为表达式的 type 和 kind 类型参数评估前 x1 + x2。
  • 但问题是 gfortran 4.8 是否以这种方式处理它
  • 我认为这应该无关紧要,因为代码在大多数迭代中都可以正常工作,只是其中一些只会提供错误。如果这应该是一个问题,那么它必须为所有迭代提供一个错误。
  • @Cocofalco,gfortran 已经能够进行混合模式运算很长时间了。它实际上是编译器中最容易实现和正确的部分之一。您可以使用 -fdump-tree-original 验证转换。
  • @Piyushkumar Patel - 仍然没有样本数据集?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-10-13
  • 1970-01-01
  • 2017-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-03
相关资源
最近更新 更多