什么会导致 GOTO 指令出现分段错误?

JM

我正在编写一个非常古老的 Fortran 77 代码,称为 LOWTRAN。它基本上是一种用于模拟大气光传播的模拟工具。
(如果您想查看完整的 lowtran 代码,您可以在此处查看,但我认为这对回答问题没有帮助)。

不幸的是,由于该代码最初是为打孔卡制作的,因此它适用于现代输入/输出方法,并产生了一些令人讨厌的故障。
这些故障很容易发现/难以修复。
为了修复其中一个,我别无选择,只能设置一个 IF 语句,其中包含一个超出 IF 语句的 GOTO,在代码中还有其他。

但是,有时,GOTO 本身会导致分段错误。它不是随机发生的,而是取决于一些似乎与该 IF 语句无关的变量。

我正在两台不同的机器上编译这个项目,其中一台没有段错误。两者都使用 gfortran 在 windows 机器(没有段错误的机器)上我使用 gfortran 7.2.0,在 Linux 机器(有段错误的机器)上我使用 gfortran 4.8.5

(我无法在 linux 机器上更新 gfortran 版本,因为我没有所需的权限)

请注意,当我编译修复程序时,两个编译器显然都会发出警告:

Warning: Legacy Extension: Label at (1) is not in the same block as the GOTO statement at (2)

这是修复

100
...
...
<Lots of code>
...
...
   if(ierror.eq.-1) then
       itype = 1
       ierror = 0
       go to 100               
   end if

雷德瓦尔德

计算机运行的代码不是您的源代码,而是机器代码。编译器从您的源代码生成该机器代码。生成可以或多或少是直接的,因此源代码的一个语句对应于几个连续的机器代码指令。但它不必是直接的。特别是,如果编译器提供优化,源代码行与机器代码指令之间的对应关系可能会中断。在这种情况下,调试器报告为SEGV 位置的行可能是错误的。

GOTO 语句的简单实现是无条件跳转机器代码指令,跳转到一个有效的代码地址。这个简单的实现永远不会产生SEGV您可能会因为错误而责怪您的编译器,但这将是一个错误编译器优化可能使事情变得混乱。您可能该 GOTO 语句附近的数组访问中或在其目标之后的代码(标记为 100 的语句)中出现错误。

尝试在关闭优化的情况下重新编译您的程序(通常使用类似 的命令行选项-O0)并重新运行您的程序。然后,您应该会在存在无效数组访问的行中看到报告的 SEGV。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章