【问题标题】:Removing a write statement is causing my program to crash删除写语句导致我的程序崩溃
【发布时间】:2018-10-17 20:05:06
【问题描述】:

我的代码中出现了一些奇怪的问题,而且我以前从未遇到过这样的问题。我有一个程序可以计算两个物体在它们自己的重力下和在 do-loop 内运行,我用它来计算它们随时间的运动,我有一个 write 语句将数据写入文件以供稍后绘制。但是,我最近想删除 write 语句,但是当我删除它时,程序在一些计算后崩溃,数据被 NaN 填充。我将在下面添加几行。

 open(unit=100,file=datafile)  !open file with name datafile (#)

 do while(ctime<totaltime)     !loop until current time > total time 
   call calc_semimajor(Objects, a)     !calculate semimajor axis
   call calc_ecc(Objects, evector, e)  !calculate eccentricty 

   at = (a0**4 - (264.0d0/5.0d0)*beta_time*ctime)**0.25 
   write(100,*) ctime, Objects(1:2), a, at, e  !write to file (#)

   !some 
   !more 
   !lines
   !here... 

 end do

 close(100) !close datafile (#)

我将此循环存储在一个子例程中以供参考,但在我制作的其他程序之前从未出现过问题。我尝试更改无效的单元号。我已经停止传入数据文件字符参数,只是在子例程中将文件定义为“data.txt”,但它不起作用。我尝试将其复制为纯文本并使用 gfortran 重新编译,但没有成功。我确实使用 nagfor 进行了编译,结果出现了下溢错误,并且在崩溃之前设法计算了更多的时间步长,但是当我删除涉及 unit=100 的行的 cmets(标有 (#))时,该错误消失了。我什至尝试过重写整个程序,看看我是否遗漏了一些东西,但即使在没有 open() 语句的情况下重写时,我也会遇到这个问题。如果这可能是一个问题,我确实在模块中存储了一些常量,这些常量是通过子例程输入的?很抱歉,如果这措辞不好,但我只是想知道是否有人以前在 Fortran 中遇到过这个问题,如果有,我该如何解决?

谢谢!

编辑:我使用 valgrind 来帮助定位问题。 (之前使用 -g 标志编译)并给出了这个重复错误

  `==14846== Conditional jump or move depends on uninitialised       value(s) 
   ==14846== by 0x40131B: leapfrog_ (/path/to/file)
   ==14846== by 0x40353C: MAIN__ (/path/to/file)
   ==14846== by 0x403939: main (/path/to/file)
   ==14846== Uninitialised value was created by a stack allocation 
   ==14846== at 0x401C12: calc_pnacceleration_ (/path/to/file)

我已经为子例程添加了一个接口,并在子例程中放置了虚拟变量,而不是使用主体中的相同变量名称。这并没有解决问题。但是,我注意到的一件事是,如果我遵守优化标志 (-O3),错误就会消失,并且会在指定的总时间内运行。这是否表明有任何特定错误?

第二次编辑:我在使用gfortran -Wall -g -fcheck=all -fbacktrace 编译时添加了输出

Simulation: In function `_start':
(.text+0x0): multiple definition of `_start'
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o: 
(.text+0x0): first defined here
Simulation: In function `_fini':
(.fini+0x0): multiple definition of `_fini'
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crti.o: 
(.fini+0x0): first defined here
Simulation:(.rodata+0x0): multiple definition of `_IO_stdin_used'
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o: 
(.rodata.cst4+0x0): first defined here
Simulation: In function `data_start':
(.data+0x0): multiple definition of `__data_start'
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o: 
(.data+0x0): first defined here
Simulation: In function `data_start':
(.data+0x8): multiple definition of `__dso_handle'
/usr/lib/gcc/x86_64-linux-gnu/5/crtbegin.o:(.data+0x0): first defined 
here 
Simulation: In function `_init':
(.init+0x0): multiple definition of `_init'
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crti.o: 
(.init+0x0): first defined here
/tmp/ccDIKQQB.o: In function `calc_ecc_':
/path/to/file/Simulation.f90:441: multiple definition of `calc_ecc_'
Simulation:(.text+0xf6): first defined here
/tmp/ccDIKQQB.o: In function `crossproduct_':
/path/to/file/Simulation.f90:466: multiple definition of 
`crossproduct_'
Simulation:(.text+0x1624): first defined here
/tmp/ccDIKQQB.o: In function `leapfrog_':
/path/to/file/Simulation.f90:262: multiple definition of `leapfrog_'
Simulation:(.text+0x26d): first defined here
/tmp/ccDIKQQB.o: In function `calc_pnacceleration_':
/path/to/file/Simulation.f90:358: multiple definition of 
`calc_pnacceleration_'
Simulation:(.text+0xe57): first defined here
/tmp/ccDIKQQB.o: In function `calc_semimajor_':
/path/to/file/Simulation.f90:426: multiple definition of 
`calc_semimajor_'
 Simulation:(.text+0xd8b): first defined here
 /tmp/ccDIKQQB.o: In function `dotproduct_':
 /path/to/file/Simulation.f90:479: multiple definition of 
 `dotproduct_'
 Simulation:(.text+0x15c1): first defined here
 /tmp/ccDIKQQB.o: In function `calc_deltaphigr_':
 /path/to/file/Simulation.f90:415: multiple definition of 
 `calc_deltaphigr_'
 Simulation:(.text+0x16ed): first defined here
 /tmp/ccDIKQQB.o: In function `main':
 /path/to/file/Simulation.f90:25: multiple definition of `main'
 Simulation:(.text+0x2be5): first defined here
 /tmp/ccDIKQQB.o: In function `plotdata_':
 /path/to/file/Simulation.f90:231: multiple definition of 
 `plotdata_'
 Simulation:(.text+0x2c20): first defined here
 /tmp/ccDIKQQB.o: In function `writeline_':
 /path/to/file/Simulation.f90:490: multiple definition of `writeline_'
 Simulation:(.text+0x3418): first defined here
 /usr/lib/gcc/x86_64-linux-gnu/5/crtend.o:(.tm_clone_table+0x0):  
 multiple definition of `__TMC_END__'
 Simulation:(.data+0x18): first defined here
 /usr/bin/ld: error in Simulation(.eh_frame); no .eh_frame_hdr table 
 will be created.
 collect2: error: ld returned 1 exit status

【问题讨论】:

  • 这是非常奇怪的行为。使用选项 gfortran -Wall -g -fcheck=all -fbacktrace 编译它——如果运气好的话,这将为您提供更多关于问题所在的信息。
  • 通常这种行为表示内存泄漏或相关(heisenbug)。我会用@chw21 指示的行编译你的程序,然后让valgrind 处理它。 valgrind --leak-check=full ./a.out
  • 除非你显示一个真实的minimal reproducible example,否则没有人可以帮助你。我们只能告诉您使用调试器。还显示您用于编译的实际和 complete 命令。包括文件名和其他所有内容。完成。
  • 把你的子程序放在一个模块中,然后use它。没有人(包括您)愿意仔细检查您的所有 interface 代码是否与子程序代码完全匹配。
  • 如果您有诸如(但不限于)未定义值和数组边界违规之类的错误,则几乎可以保证当 write() 阻止优化时行为会发生变化。下面的答案似乎特定于 gfortran,您需要的一些检查需要 -O。对于其他编译器,最好先不使用 -O 进行调试。

标签: fortran nan underflow


【解决方案1】:

使用以下选项编译您的代码: -Wall -fcheck=all -g -O -finit-real=nan -ffpe-trap=invalid 修复所有警告。运行代码时使用“y”和“1” 作为您的输入。当它因为使用未初始化而死时 变量。使用gdb 查看核心转储。

【讨论】:

  • 这是一个答案吗?
  • 这是一个反问句吗? OP 在使用接口块而不是模块时没有出错。 OP 正在使用未初始化的变量。将子例程放在模块中不会神奇地修复未初始化的变量。 tim18,查找问题所需的最低选项是 -finit-real=nan -ffpe-trap=invalid。其他编译器也有类似的选项。
  • 如果您确实发现了实际错误,请在此处显示。教别人如何调试很有用,但这可以在评论中。或者在一半的答案中。但是OP问他的错误在哪里而不是如何调试。我猜你已经找到它了,为什么还要隐藏它?
  • 不,根本不是反问。我不清楚你写的内容是否回答了这个问题。似乎至少还有其他读者也不确定。
  • 所以只是希望您格式化您传递的文本,仅此而已。这是正确的行为。不要在没有格式化的情况下粘贴任何内容。只需在问题编辑器中单击{}。阅读它给您的重要信息以及欢迎tour 等帮助页面。
猜你喜欢
  • 2021-03-22
  • 2011-12-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多