In my project, I have a module (read_data) with many PUBLIC module variables
(either PARAMETERs or PROTECTED) of intrinsic types:
80+ integer(4); 30+ real(8); 1 real(8) array, size 12; and 2 complex(8)
I have a subroutine (errchk) contained in the module that performs many
checks on these PUBLIC entities for errors using an explicit interface to
subroutine (relevant) through USE. And today, I added one additional call
inside errck, and surprisingly, the program received SIGABRT: Process abort
much further downstream in the program than the initial call to errchk.
When the SIGABRT is reached, the traceback shows it is inside of
a subroutine of a module that is using read_data (without an ONLY clause).
Here's a brief outline of the module, read_data:
$ cat read_data.f90
use exceptions, only: relevant
integer(4), protected, public :: a, b, c, [...]
real(8), protected, public :: x, y, [...]
: ! other declarations omitted for brevity
call relevant(a, b == 2)
call relevant(x, y /= 0d0)
: ! a decent number of calls to relevant() and other procedures that ...
: ! ... pass in the PUBLIC module entities as actual arguments.
! one more call to `relevant` throws the SIGABRT further in the program
call relevant(y, x > 0d0) ! comment this out, and the program does not
! curiously, if the above is commented out, and below is commented in, ...
! ... there is _no_ SIGABRT thrown in the program.
!call relevant(y, .true.)
end subroutine errchk
end module read_data
Note that relevant and the other omitted error-checking procedures only have
one side-effect to them: writing to stdout.
And also note that errchk() is only called in the main program unit once.
The line at which SIGABRT signal is thrown is accessing some elements of an
allocated array component of a derived type: a seemingly harmless statement.
If printed out before SIGABRT is thrown, the array as well as the integer
used to access the array elements are defined -- nothing looks anomalous.
I first observed the SIGABRT with -O3, and then with -Og as well.
Removing all optimization flags made the program no longer throw the
which was surprising to me. Specifically, my no-optimization compiler flags
FFLAGS = -g -ggdb -pedantic -Wextra -Wconversion -Wno-compare-reals \
-Wcharacter-truncation -Wimplicit-interface \
-Wall -fwhole-file -std=f2008 -fall-intrinsics \
... only differing by adding the -O* flag accordingly. Also testing with
the program runs successfully without a SIGABRT. So then, there is likely
something happening during the optimization routines that is causing this
My next course of action was then to determine specifically what flags are
by -Og that could be causing this issue. By doing the following commands,
I got a nice list showing the differences:
$ gfortran -Q -g --help=optimizers >> gopts.txt
$ gfortran -Q -Og --help=optimizers >> Ogopts.txt
$ diff gopts.txt Ogopts.txt >> gvsOg.txt
(My version of gfortran is 7.4.0 for Ubuntu 18.04.1, installed through apt.)
The file gvsOg.txt then outlines the following flags that are enabled by
-fcombine-stack-adjustments -fcompare-elim -fcprop-registers -fdefer-pop \
-fforward-propagate -fguess-branch-probability -fipa-profile
-fipa-reference -fomit-frame-pointer -freorder-blocks -fshrink-wrap
-ftree-builtin-call-dce -ftree-ccp -ftree-ch -ftree-coalesce-vars
-ftree-dce -ftree-dominator-opts -ftree-dse -ftree-fre -ftree-sink
Appending these flags onto FFLAGS (as defined above), however, does not
cause a SIGABRT.
Commenting them out and putting a -Og in its place still causes a SIGABRT.
Here is where my current debugging attempts have hit a wall.
Since it is related to (non-allocatable) PUBLIC module entities (in
I have a suspicion it could be related to how gfortran is storing these
variables in memory,
esp. on the stack. But I do not know how to control/query this sort of
So my main questions for the Fortran mailing list are:
1. Do you have any ideas on how to further diagnose, or even solve, the
2. Since enabling the flags outlined in gvsOg.txt do not signal the
is apparent that there is more done by gcc when turning on -Og. Is there
I'm missing here with these three commands to determine what
enabled by -Og?
If need be, I can attempt to make a minimal illustrative example of this
but that would take some more time to decouple this from the whole project.
Thanks for your time,
On Wed, Sep 04, 2019 at 09:09:24PM -0500, Ethan Beyak wrote:
> FFLAGS = -g -ggdb -pedantic -Wextra -Wconversion -Wno-compare-reals \
> -Wcharacter-truncation -Wimplicit-interface \
> -Wall -fwhole-file -std=f2008 -fall-intrinsics \
> -fopenmp -ffpe-summary='invalid,zero,overflow,underflow'
> ... only differing by adding the -O* flag accordingly. Also testing with
> the program runs successfully without a SIGABRT. So then, there is likely
> something happening during the optimization routines that is causing this
Have you tried adding -fcheck=all to your options?
Have you tried adding -fcheck-array-temporaries to your options?
Have you tried to manipulate your stacksize (see
There is also -fstack-arrays. Not sure how if it will help.
Do you require the -fopenmp option? This option implies
the -frecursive option. -frecursive can force local arrays
onto the stack.
> So my main questions for the Fortran mailing list are:
> 1. Do you have any ideas on how to further diagnose, or even solve, the
What does the the limits command show for your stack size?
Can you increase?
Run the SIGABRTing executable under valgrind.
|Free forum by Nabble||Edit this page|