Enabling -Og causes SIGABRT calling procedures with module variables as actual arguments

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Enabling -Og causes SIGABRT calling procedures with module variables as actual arguments

Ethan Beyak
Hi all,

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
different
checks on these PUBLIC entities for errors using an explicit interface to
another
subroutine (relevant) through USE. And today, I added one additional call
to relevant
inside errck, and surprisingly, the program received SIGABRT: Process abort
signal,
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
module read_data
use exceptions, only: relevant
implicit none

private

integer(4), protected, public :: a, b, c, [...]
real(8), protected, public :: x, y, [...]
: ! other declarations omitted for brevity

contains

  subroutine errchk()

  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
SIGABRT.

  ! 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
indices
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
SIGABRT,
which was surprising to me. Specifically, my no-optimization compiler flags
are:

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
-O0,
the program runs successfully without a SIGABRT. So then, there is likely
something happening during the optimization routines that is causing this
SIGABRT.

My next course of action was then to determine specifically what flags are
enabled
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
-Og:

 -fcombine-stack-adjustments -fcompare-elim -fcprop-registers -fdefer-pop \
 -fforward-propagate -fguess-branch-probability -fipa-profile
-fipa-pure-const \
 -fipa-reference -fomit-frame-pointer -freorder-blocks -fshrink-wrap
-fsplit-wide-types \
 -ftree-builtin-call-dce -ftree-ccp -ftree-ch -ftree-coalesce-vars
-ftree-copy-prop \
 -ftree-dce -ftree-dominator-opts -ftree-dse -ftree-fre -ftree-sink
-ftree-slsr -ftree-ter

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
read_data),
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
information
with gfortran/gcc.

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
problem?
2. Since enabling the flags outlined in gvsOg.txt do not signal the
SIGABRT, it
   is apparent that there is more done by gcc when turning on -Og. Is there
something
   I'm missing here with these three commands to determine what
specifically is
   enabled by -Og?

If need be, I can attempt to make a minimal illustrative example of this
behavior,
but that would take some more time to decouple this from the whole project.

Thanks for your time,

Ethan
Reply | Threaded
Open this post in threaded view
|

Re: Enabling -Og causes SIGABRT calling procedures with module variables as actual arguments

Steve Kargl
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
> -O0,
> the program runs successfully without a SIGABRT. So then, there is likely
> something happening during the optimization routines that is causing this
> SIGABRT.

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
-fmax-stack-var-size option)?
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
> problem?

What does the the limits command show for your stack size?
Can you increase?

Run the SIGABRTing executable under valgrind.

--
Steve