【问题标题】:"Segmentation Fault (core dumped)" error in Fortran gfortran linuxFortran gfortran linux中的“分段错误(核心转储)”错误
【发布时间】:2013-12-08 12:20:53
【问题描述】:

我正在创建一个程序,它将分析一个目录中的文件 .fits,然后它将在另一个目录中创建另一个文件 .txt。它只是一个转换器。

当我尝试执行程序(编译正常)时,它给了我一条错误消息:

程序收到信号 SIGSEGV:分段错误 - 内存引用无效。

此错误的回溯: 0 0x7FC5ADB1C117 1 0x7FC5ADB1C6F4 2 0x7FC5AD46C0AF fitcore.c:6893 处的 ffthdu 中的 3 0x44E704 Codigo.f90 的 MAIN__ 中的 4 0x405101:? 分段错误(核心转储)

还有另一个信息:当我删除执行“写入新的 .txt 转换器文件”部分的程序时,程序运行正常,它会读取整个 .fits 文件!这是这段:

arq='spec-1.txt'
open (29,file=arq,status='unknown')
write(29,*) '  l(n)                      fa(n)'
do n=1,naxes
   write(29,*) l(n), fa(n)
end do

我已将变量“arq”声明为字符,一切正常。当我删除此拉伸时,不再出现分段错误,但我现在不知道该怎么办,因为我需要将信息传递给此 .txt!并且“arq”字符串不完整,因为我现在只是测试,稍后我将添加整个目录。

这是完整的程序,我正在使用“gfortran Codigo.f90 -o TESTE -Lcfitsio -lcfitsio”来编译它:

implicit none

integer largo,status,hdnum,n,keysexist,keysadd,bitpix,naxis
integer naxes,readwrite,blocksize
integer i,j,k
integer iF(3),iT(3),iw(3),iwe,il,ib,jb,iFold,iFoldmin(3)
integer iFoldmax(3),iFoldopt(3)
integer iMiMy,iMo,Tymin,Tymax,Timin,Timax,Tyoung(3),Tint(3),Told
integer i912,i45000,Tyin,Tiin,nrows,ncols,datacode,repeat,width
integer nlam_ext
integer fKD,fKK,fKKD
parameter (nlam_ext = 1145)
CHARACTER NAMECH*256,name2*256,alibi*1000,card*80,code*14
CHARACTER arq*1000
CHARACTER name(7)*256,namein*256,nebname*256,nameout*256
CHARACTER nameindva*256,nameoutdva*256,mid(3)*4,line*1000
real fa(10000),fcs(10000),noiz(10000),mask(10000)
real*8 l(10000)
real*8 w_ext(nlam_ext),alam_ext(nlam_ext)
REAL*8 F(3,7),T(3,35),Fl(3,7,36,6900),w(3,6900),y(6900),ye(6900)
REAL*8 SN(6900),xe(6900)
real*8 CHISQU,CHISQUmin(3),CHISQUup,CHISQUdown,CHISQUmid,nf,nfup
real*8 nfdown,nfmid,nfopt(3)
real*8 t4020,y4020,i4020,o4020,t4860,y4860,i4860,o4860
real*8 xd(10000),yd(10000),absorb,ebminv,ke,redshift
real*8 xf(10000),yf(10000),yp(10000)
real*8 x(6900)
real*8 flueks(10000),extcurve(10000)
real*8 xg,yg(10000),x2,y2(10000)
REAL*8 sng,ewa,ewb,ewg,hha,hhb,oldage(3)
REAL*8 Mo(9),MiMy(9),Myoung,Mint,Mold,Myopt(3),Miopt(3),Moopt(3)
REAL*8 Fyoung,Fint,Fold(7),Noise
real*8 a,b,c, plyus,minus,xx,nebemm(6900),yy(6900)
real*8 Flyoung(6900),Flint(6900),Flold(6900)
real*8 ha,Oiii4959,Oiii5007,Nii,Nii2,Sii6717,Sii6731,Oii3727,Hei
real*8 hhg,hg,Oiii4363,Oii7319,Oii7330,Nii6548,Nii6584
real*8 R23,R3,P,XNII,xis,yps,O3N2,R,Z,k0,k1,k2,q,logq
real*8 OHNII,OHZ,OHMcG,OHP,OHKD,I2lOH,OHKK
real*8 OHKKD,OHKKbe,OHPPN2,OHPPO3N2,OHP05,I2lOHbef
logical anynull
  ebminv = 0.
namech='/home/matheus/Desktop/IC/Spectra/Elliptical/spec-0266-51602-0467.fits'
write(6,*)namech
readwrite=0
status=0
call ftopen(17,namech,readwrite,blocksize,status)
call ftghsp(17,keysexist,keysadd,status)
do n=1,keysexist
  call ftgrec(17,n,card,status)
  if (card(1:9)=='CRVAL1  =') then
    read(card,'(a9,e21.14)')alibi,a
  endif
  if (card(1:6)=='NAXIS1') then
    read(card,'(a9,i21)')alibi,
   endif
  if (card(1:6)=='Z     ') then
    read(card,'(a9,e21.14)')alibi,redshift
  endif
  if (card(1:6)=='SN_G  ') then
    read(card,'(a9,e21.14)')alibi,sng 
  endif
enddo
l(1)=10.**a/(1.+redshift)
l(naxes)=10.**(a+0.0001*float(naxes-1))/(1.+redshift)
  do n=1,naxes
  l(n)=10.**(a+0.0001*float(n-1))
enddo
 call ftthdu(17,hdnum,status)
call ftgidt(17,bitpix,status)
call ftgtcl(17,1,datacode,repeat,width,status)
call ftgpve(17,1,1,naxes,0.,fa,anynull,status)
call ftgpve(17,1,naxes+1,naxes,0.,fcs,anynull,status)
call ftgpve(17,1,2*naxes+1,naxes,0.,noiz,anynull,status)
call ftgpve(17,1,3*naxes+1,naxes,0.,mask,anynull,status)
call ftclos(17,status) 
write(6,*)'spectra read in',l(1),l(naxes)
arq='spec-1.txt'
open (29,file=arq,status='unknown')
write(29,*) '  l(n)','                      fa(n)'
do n=1,naxes
   write(29,*) l(n), fa(n)
end do


 close(25)
write(6,*)
write(6,'(a)')'Justice is done'
 end

实际上发生错误是因为它总是给 naxes 一个零值!

【问题讨论】:

  • 请缩小一点!您可以首先使用调试选项 (-g) 编译代码并通过 gdb 运行它。这应该给你(和我们)有价值的提示;-)
  • 咨询software.intel.com/en-us/articles/…报告您的调查结果。
  • 如果不知道如何使用gdb,请安装ddd。如果您使用 -g 构建了代码,则在加载可执行文件时,您应该会看到所有源代码。

标签: linux fortran


【解决方案1】:

Fortran 中致命内存错误的最常见原因是非法数组下标以及调用过程(子例程或函数)的参数与过程声明的参数之间的不一致。首先,打开运行时下标检查。使用 gfortran、-fcheck=bounds 或更好的工具,使用 -fcheck=all 打开额外的运行时检查。对于过程参数问题,将所有过程放入模块中,use 来自调用任何过程的任何例程中的那些模块。这将使编译器能够在编译时检查参数的一致性。

【讨论】:

  • 谢谢大家!我添加 -fcheck=all 以查看它尝试执行程序时发生了什么错误,我得到了:在文件 Codigo.f90 Fortran 运行时错误的第 65 行:索引 '0' of array 'l' below lower bound of 1 实际上我认为问题出在“naxes”上!因为当我编译它时将“naxes”替换为“2”,例如,它没有给我结果(当然)但错误消失了!有人可以告诉我为什么会发生“naxes”这个错误吗??
  • 您正在访问不存在的数组元素。您声明数组以 1 开头但使用了 0。因此,请重写代码以不访问数组“l”的不存在元素 0,或重新声明数组“l”以索引 0 而不是 1 开头,例如 real*8 l(0:10000) .
  • 谢谢!错误消失了!但是程序只是不写值,它总是给“naxes”值“0”! ://
  • 我的建议:您应该从每个 fitio 例程调用中检查 status 的值。检查所有输出,看看它是否有意义。找到最早的问题并解决它,而不是您注意到的第一个问题。使用互动工具fv 找出您应该期待什么。
  • 在 7 年后帮助了我。谢谢:)
【解决方案2】:

谢谢大家!我添加了 -fcheck=all 以查看它尝试执行程序时发生了什么错误,我明白了:

在文件 Codigo.f90 的第 65 行 Fortran 运行时错误:数组“l”的维度 1 的索引“0”低于 1 的下限

实际上我认为问题出在“naxes”上!因为当我编译它时将“naxes”替换为“2”,例如,它没有给我结果(当然)但错误消失了!

有人可以告诉我为什么会发生“naxes”这个错误吗?再次感谢大家!!!

【讨论】:

  • 在您发布的代码中,变量naxes 没有给定值。它经常出现在赋值的 rhs 中,经常用于索引到数组中,没有任何地方给它赋值。坦率地说,你很幸运,它被设置为 0 而不是其他值。
猜你喜欢
  • 2014-06-17
  • 1970-01-01
  • 1970-01-01
  • 2013-06-21
  • 2014-08-04
  • 2012-11-19
  • 1970-01-01
  • 1970-01-01
  • 2015-06-25
相关资源
最近更新 更多