Keep getting segmentation faults on verification models when compiling on Linux ( GNU and Intel compilers )

I think the code is really old and the newest compilers are more strict with what they will tolerate. Here’s a snippet of my Makefile:

CFLAGS = -g -std=gnu99 -w -O2 -fopenmp -I ../../../SPOOLES.2.2 -DARCH="Linux" -DSPOOLES -DARPACK -DMATRIXSTORAGE -DUSE_MT=1 

FFLAGS = -g -fbacktrace -Wall -O0 -fopenmp 

Compiling with Spooles on Rocky Linux 9.6. I keep getting segmentation fault with this verification model:

beamfstrucdamp.inp

If I change the fortran flags optimization to -O2, then it will run ok along with all the rest of the verification models. However, with Intel compiler ( OneAPI 2025 ) , both -) -O2, and -O0 will give segmentation faults. But -O0 will at least run 95% of the verification models ok. -O2 won’t run any models.

Here is a snippet of my Makefile for Intel Oneapi

CFLAGS = -w -D_POSIX_C_SOURCE=199309L -O3 -std=c90 -fopenmp -DARCH="Linux" -DINTSIZE64 -DMKL_ILP64 -DPARDISO -DLONGLONG -DARPACK -DMATRIXSTORAGE -DUSE_MT=1
FFLAGS = -w -O0 -fopenmp -i8

I tried looking at the backtrace with GNU debugger but seems a lot to investigate.. Will keep poking around..

1 Like

@feacluster

I think the problem with >>beamfstrucdamp.inp<< rely on ccx_2.22 only, at least this is my experience since I don’t get segmentation fault with ccx_2.21 and ccx_2.23, spoole solver running Debian Trixie complied with gcc/gfortran 14.2.0

Furthermore, to whom it may concern, the official source code for ccx_2.23 has an obvious bug in the file readnewmesh.c.
The function readnewmesh has been declared as a void function and on the exit code to return a NULL, which depending on how the compiler interprets the code can risk to cause a segmentation failure.
so instead of
return NULL;
the statement just could be comment;
// return NULL;

It’s important to note that the multithreading function *genratiomt at the end of the readnewmesh file shall exit with a return NULL; even it is declared as a void. It’s required because the argument for the function is allocated on stack and needed to be removed on exit.

2 Likes

I did some investigation and it seems the segmentation faults are due to use of “uninitialized variables”. Compilers treat these differently and when you enable optimizations that can further change the expected behavior.

Seems there are 1700 uninitialized variable warnings in the Calculix fortran code.

beamfstrucdamp.inp is one example that fails due to use of uninitialized variable. I asked about it on reddit in the fortran community and got some good insight:

https://www.reddit.com/r/fortran/comments/1p8jm84/how_to_find_cause_of_segmentation_fault_using_gnu/

2 Likes

@feacluster , I see you already got a solution with help on reddit, so no need to repeat that, but for others whom skip the explanation on reddit the quick fix will be ex. to change the fortran compiler optimization flag to -O2 instead of -O0

2 Likes

Thanks for investigating!

The issue is definitely related to the compiler version.

I can run these examples without any problems with compiled version of the latest code on GitHub using GNU’s gcc/gfortran version 15 or Intel’s icc/ifort compilers version 2022.

I run into the same issue using Intel’s 2024 icx/ifx compilers. However, disabling the optimization flags, fixes it. (Edit: apparently not all test cases)

Looks like there is some work to do resolving compiler warnings that have been around some time :slight_smile:

2 Likes

Thanks, yes are correct that with O2 optimization, the segmentation faults go away. But that only works with GNU compiler and Spooles. WIth 2025 Intel Oneapi O2 it gives segmentation faults on all models. O0 gives segmentation on some models..

Perhaps there is some additional setting with Intel compiler to deal with this? But I think it makes more sense to update the code to not have these “bugs”..

Could you also share the snippet of your makefile again ( just the top few lines )..

@feacluster Once with ccx_2.12 I had a vision, that I would correct any/all warnings, and then I actual made a correction in the ccx_2.12.c for this missing allocation of the cs matrice,

if(ntie_>0){
  NNEW(tieset,char,243*ntie_);
  NNEW(tietol,double,3*ntie_);
  NNEW(cs,double,17*ntie_);
}
// initialize cs to a minimum size just in case it hasn't been allocated
if (cs == NULL) NNEW(cs,double,17);

in ccx_2.22.c it would be in line 456 …… but then ccx_2.14 was release and I gave up. decided to live with a minimum of effort on new releases. Never mind :slight_smile: You ask for the few first in my Makefile


CFLAGS = -O2 -Wall -I ../../SPOOLES.2.2 -DARCH="Linux" -DSPOOLES -DARPACK - DMATRIXSTORAGE -DNETWORKOUT -DUSE_MT
FFLAGS = -O2 -Wall -std=legacy -Wno-unused-variable -Wno-unused-dummy-argument
FFLAGS += -cpp
# -cpp flag for c preprocessor in ccx_2.23 fortran module move.f

CFLAGS += -DPARDISO -I /opt/intel/oneapi/mkl/latest/include
#CFLAGS += -DTAUCS -Wno-implicit-function-declaration -Wno-unused-variable
#CFLAGS += -DINTSIZE64
#FFLAGS += -fdefault-integer-8

CC=gcc
FC=gfortran

2 Likes

Great! Adding that to ccx_2.22.c line 456 worked. Now nearly all the verification models complete using icx/ifx. A couple still give segmentation faults if I set optimization to zero. But with O2 they complete.

Interesting you are using gcc with Intel’s pardiso . Why not use all Intel compiler?

1 Like

@feacluster I’m not sure, that the intel fortran compiler was free for download back then, maybe that was the reason, and when mixing different compiler language it should minimize compatibility failures when they from cave.

1 Like

I agree. We should talk to Guido about this and, with the help of AI tools, start migrating the code to more modern forms of Fortran.

@jbr Old school Fortran 77 is probably that computer language which generate the fastest code in the world for mathematical calculation, because there is no overhead at all, and every thing are call by reference. I you don’t believe me, you should do the test by your self.

Readability and stability rely primary on the programmers and not by the language, as an example you should try compiling PrePoMax, which is written i C#, it generate also a lot of warnings about loss of digits etc.

I think you are assuming that my concerns come from not understanding Fortran 77 or its capabilities. That is not the case. F77 was my first programming language and I actually like it. But that does not justify holding onto outdated coding patterns when modern compilers are clearly moving on.

The reality is simple: compilers evolve, legacy behavior gets deprecated, and codebases that stay frozen in old standards eventually break. We are already seeing that with the segmentation faults and inconsistent behavior depending on compiler or architecture. These are not “mysteries”; they are symptoms of relying on constructs that newer compilers no longer handle the same way.

Continuing to defend old F77 idioms just because they used to work, or because they are considered “the fastest code in the world for mathematical calculation”, is not a sustainable strategy. If anything, it puts the project at risk. From my perspective, it is update or fall behind and eventually die. At some point, compilers will stop accommodating these legacy patterns altogether, and then the choice disappears.

My goal is to make sure the code remains buildable, portable, and maintainable going forward. Ignoring the direction compilers are heading will only create more issues, not fewer; and we already have enough other issues of more interest to deal with.

This is not just my personal preference. There is a whole body of work from NASA, DOE labs, and the climate-modeling community arguing that large legacy F77 codes have to be modernized-migrated toward Fortran 90+ and refactored- if they are going to remain maintainable and compatible with evolving compilers and hardware. See, for example, work on modernizing F77 legacy codes at NASA and the streamlining of the RELAP5-3D code at Idaho National Lab.

Segmentation faults using the latest gnu/intel compiler versions with -O0 or -O2 should be fixed with commit:

The issue was an undefined behaviour in the code that compilers can treat differently. This lead to a segmentation fault since cs was accessed before it had been allocated for some compiler/optimization combinations.

Could you check if the fix works for you @feacluster?

1 Like

(post deleted by author)

Many thanks for looking into it! Seems you had to modify several files.. I tested with Intel 2025 Oneapi and now beamfstrucdamp.inp runs ok . But only if I do -O0 . With -O1 or -O2 optimization it will fail with segmentation fault.

I am not sure how important optimization is to speed. Probably insignificant with modern cpus.. So for now, looks we are good. I will do some more testing when I get time..

1 Like