I am working on a very old, fortran 77 code called LOWTRAN.
It basically is a simulation tool used to model atmospheric light propagation.
(if you wish to see the complete lowtran code you can check it out here though I dont think it will help in answering the question).
Unfortunately, as that code was originally made for punch-cards, it was adapted for modern input/output methods and that created a few nasty glitches.
Those glitches are of the easy to spot/hard to fix kind.
In order to fix one of them i had no other choice than to setup an IF statement, which contains a GOTO that goes outside the IF statement, somwere else in the code.
However, Sometimes, the GOTO itself causes a segmentation fault. It does not happend randomly, it rather depends on a few variables that seem unrelated to that IF statement.
I am compiling this project on two different machines and one does not segfault. Both use gfortran On the windows Machine (the one that does not segfault) i use gfortran 7.2.0 and on the Linux Machine (the one that has segfaults) i use gfortran 4.8.5
(i can't update the gfortran version on the linux machine as i dont have the required rights)
Note that Both compilers obviously raise a warning when i compile my fix:
Warning: Legacy Extension: Label at (1) is not in the same block as the GOTO statement at (2)
here is the fix
100
...
...
<Lots of code>
...
...
if(ierror.eq.-1) then
itype = 1
ierror = 0
go to 100
end if
The code that the computer runs is not your source code, but rather machine code. The compiler generates that machine code from your source code. The generation can be more or less direct, so one statement of your source code corresponds to a few contiguous machine code instructions. But it need not be direct. In particular, if the compiler provides optimizations, the correspondence between lines of your source code and the machine code instructions can break down. In that case, the line that a debugger reports as the location of the SEGV can be wrong.
The simple implementation of a GOTO statement is an unconditional jump machine code instruction, jumping to a valid code address. That simple implementation would never result in a SEGV. You might be tempted to blame your compiler for being buggy, but that would be a mistake. Compiler optimzation has probably confused things. You probably have a fault in an array access near that GOTO statement, or the code just after its destination (the statement labelled 100).
Try recompiling your program with optimizations turned off (typically with a command-line option like -O0
) and rerunning your program. You should then see the SEGV reported at the line where there is an invalid array access.