g++ -O2 OK, -O3 Segmentation fault

Discussion in 'C++' started by Rares Vernica, Jul 7, 2008.

  1. Hello,

    I have a strange problem.

    I compile my code with g++ (GCC) 4.1.2. My code runs just fine if I use
    the -O2 optimization flag. valgrind does not report any memory leak.

    When I use the -O3 flag, everything falls apart. The program reports
    Segmentation fault. valgrind reports some Invalid read.

    Moreover, if I cout something near the line for which valgrind reports
    the invalid read, then everything works fine, no more segmentation faults
    or invalid reads.

    Thanks in advance,
    Rares
    Rares Vernica, Jul 7, 2008
    #1
    1. Advertising

  2. Rares Vernica wrote:
    > Hello,
    >
    > I have a strange problem.
    >
    > I compile my code with g++ (GCC) 4.1.2. My code runs just fine if I use
    > the -O2 optimization flag. valgrind does not report any memory leak.
    >
    > When I use the -O3 flag, everything falls apart. The program reports
    > Segmentation fault. valgrind reports some Invalid read.
    >
    > Moreover, if I cout something near the line for which valgrind reports
    > the invalid read, then everything works fine, no more segmentation faults
    > or invalid reads.


    See if this persists on the latest version of GCC.

    Without looking at the code I'd point the finger at the compiler but
    strange things can happen that may expose a bug in your code.

    If it is a compiler bug, then file a bug against GCC - they're very good
    at pointing you at a workaround and also fixing the bug in later releases.

    G
    Gianni Mariani, Jul 7, 2008
    #2
    1. Advertising

  3. Gianni Mariani schrieb:

    > Without looking at the code I'd point the finger at the compiler but
    > strange things can happen that may expose a bug in your code.


    Eh? Without looking at the code I'd point my finger at the programmer.
    Sounds like a definite case of invoked UB which changes its
    manifestation with increased optimization level. Maybe stack corruption
    or such. Valgrind may miss it with -O2 because no illegal accesses take
    place with -O2 - the story may be different with -O3.

    Interesting might be assembly level debugging, diff the objdump of -O2
    against -O3 and inspect the location.

    Regards,
    Johannes

    --
    "Wer etwas kritisiert muss es noch lange nicht selber besser können. Es
    reicht zu wissen, daß andere es besser können und andere es auch
    besser machen um einen Vergleich zu bringen." - Wolfgang Gerber
    in de.sci.electronics <47fa8447$0$11545$>
    Johannes Bauer, Jul 7, 2008
    #3
  4. Rares Vernica <> writes:

    > I compile my code with g++ (GCC) 4.1.2. My code runs just fine if I use
    > the -O2 optimization flag. valgrind does not report any memory leak.
    >
    > When I use the -O3 flag, everything falls apart. The program reports
    > Segmentation fault. valgrind reports some Invalid read.
    >
    > Moreover, if I cout something near the line for which valgrind reports
    > the invalid read, then everything works fine, no more segmentation faults
    > or invalid reads.


    It was a bug in my code. :( Now it works fine with -O3.

    Still, I am a little bit confused how the bug generated a segmentation
    fault only with -O3.

    Thanks.
    Rares
    Rares Vernica, Jul 7, 2008
    #4
  5. Rares Vernica

    Ian Collins Guest

    Rares Vernica wrote:
    > Rares Vernica <> writes:
    >
    >> I compile my code with g++ (GCC) 4.1.2. My code runs just fine if I use
    >> the -O2 optimization flag. valgrind does not report any memory leak.
    >>
    >> When I use the -O3 flag, everything falls apart. The program reports
    >> Segmentation fault. valgrind reports some Invalid read.
    >>
    >> Moreover, if I cout something near the line for which valgrind reports
    >> the invalid read, then everything works fine, no more segmentation faults
    >> or invalid reads.

    >
    > It was a bug in my code. :( Now it works fine with -O3.
    >
    > Still, I am a little bit confused how the bug generated a segmentation
    > fault only with -O3.
    >

    The Undefined in Undefined Behaviour?

    --
    Ian Collins.
    Ian Collins, Jul 7, 2008
    #5
  6. Rares Vernica wrote:
    > Rares Vernica <> writes:

    ....
    > Still, I am a little bit confused how the bug generated a segmentation
    > fault only with -O3.


    Using uninitialized memory ?
    Gianni Mariani, Jul 8, 2008
    #6
  7. Rares Vernica

    James Kanze Guest

    On Jul 7, 9:59 pm, Gianni Mariani <> wrote:
    > Rares Vernica wrote:
    > > I have a strange problem.


    > > I compile my code with g++ (GCC) 4.1.2. My code runs just
    > > fine if I use the -O2 optimization flag. valgrind does not
    > > report any memory leak.


    > > When I use the -O3 flag, everything falls apart. The program
    > > reports Segmentation fault. valgrind reports some Invalid
    > > read.


    > > Moreover, if I cout something near the line for which
    > > valgrind reports the invalid read, then everything works
    > > fine, no more segmentation faults or invalid reads.


    > See if this persists on the latest version of GCC.


    > Without looking at the code I'd point the finger at the
    > compiler but strange things can happen that may expose a bug
    > in your code.


    While one can never exclude the possibility of a compiler bug,
    especially when optimization is involved, I'd consider some
    undefined behavior in his code as a more likely reason. The
    time when I found more errors in the compiler than in my code
    are long past.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Jul 8, 2008
    #7
  8. Rares Vernica a écrit :
    > Rares Vernica <> writes:
    > Still, I am a little bit confused how the bug generated a segmentation
    > fault only with -O3.


    -O3 turns on the -finline-functions, -fweb and -frename-registers options.

    If you have a mind to it, you can investigate which of the optimization
    trigger the bug. However, UB is UB so don't expect great discoveries.

    As a matter of fact, you could make benchmarks also: some optimizations
    generate much more code (like inlining) and thus reduce performances on
    some systems.

    --
    Michael
    Michael DOUBEZ, Jul 8, 2008
    #8
  9. Rares Vernica wrote:
    > It was a bug in my code. :( Now it works fine with -O3.
    >
    > Still, I am a little bit confused how the bug generated a segmentation
    > fault only with -O3.


    The "I added a debug print command and now it doesn't crash" is a
    typical symptom of something writing out of boundaries and messing up
    things. I don't know exactly what valgrind checks, but if the write
    happens to be done on valid, allocated memory (but not allocated by the
    piece of code which is doing the writing) it may be valgrind just
    doesn't notice.

    -O3 probably produces code/data which is arranged differently from -O2
    and just happened to show the symptom. Your -O2 code was most probably
    also erroneous, but the erroneous code happened to write somewhere where
    it didn't matter (or, at least, didn't cause a crash).
    Juha Nieminen, Jul 8, 2008
    #9
  10. Rares Vernica

    Lionel B Guest

    On Tue, 08 Jul 2008 10:23:38 +0200, Michael DOUBEZ wrote:

    > Rares Vernica a écrit :
    >> Rares Vernica <> writes: Still, I am a little bit
    >> confused how the bug generated a segmentation fault only with -O3.

    >
    > -O3 turns on the -finline-functions, -fweb and -frename-registers
    > options.
    >
    > If you have a mind to it, you can investigate which of the optimization
    > trigger the bug. However, UB is UB so don't expect great discoveries.
    >
    > As a matter of fact, you could make benchmarks also: some optimizations
    > generate much more code (like inlining) and thus reduce performances on
    > some systems.


    Not relevant to this thread, but inlining may sometimes actually *reduce*
    code size - e.g. for very small functions (a common case for inlining)
    where the function call (code size) overhead might actually be larger
    than the inlined function code itself...

    int foo(const int n)
    {
    return n*n;
    }

    int main()
    {
    return foo(3);
    }

    On my system (compiled with g++ and -O<whatever>) this produces a smaller
    executable when foo() is declared inline.

    --
    Lionel B
    Lionel B, Jul 8, 2008
    #10
  11. Lionel B a écrit :
    > Not relevant to this thread, but inlining may sometimes actually *reduce*
    > code size - e.g. for very small functions (a common case for inlining)
    > where the function call (code size) overhead might actually be larger
    > than the inlined function code itself...
    >
    > int foo(const int n)
    > {
    > return n*n;
    > }
    >
    > int main()
    > {
    > return foo(3);
    > }
    >
    > On my system (compiled with g++ and -O<whatever>) this produces a smaller
    > executable when foo() is declared inline.


    In gcc, the functions considered for inlining are much bigger (default
    is 600 lines of pseudocode IIRC) unless you tune it to allow only
    smaller functions.

    In practice, I would use -O3 optimization on very small parts of the
    project.

    --
    Michael
    Michael DOUBEZ, Jul 8, 2008
    #11
  12. Rares Vernica

    Lionel B Guest

    On Tue, 08 Jul 2008 11:40:10 +0200, Michael DOUBEZ wrote:

    > Lionel B a écrit :
    >> Not relevant to this thread, but inlining may sometimes actually
    >> *reduce* code size - e.g. for very small functions (a common case for
    >> inlining) where the function call (code size) overhead might actually
    >> be larger than the inlined function code itself...
    >>
    >> int foo(const int n)
    >> {
    >> return n*n;
    >> }
    >>
    >> int main()
    >> {
    >> return foo(3);
    >> }
    >>
    >> On my system (compiled with g++ and -O<whatever>) this produces a
    >> smaller executable when foo() is declared inline.

    >
    > In gcc, the functions considered for inlining are much bigger (default
    > is 600 lines of pseudocode IIRC) unless you tune it to allow only
    > smaller functions.


    Sure, the full(ish) story is:

    -fno-inline
    Don't pay attention to the inline keyword. Normally this option is
    used to keep the compiler from expanding any functions inline. Note that
    if you are not optimizing, no functions can be expanded inline.

    -finline-small-functions
    Integrate functions into their callers when their body is smaller
    than expected function call code (so overall size of program gets
    smaller). The compiler heuristically decides which functions are simple
    enough to be worth integrating in this way.

    Enabled at level -O2.

    -finline-functions
    Integrate all simple functions into their callers. The compiler
    heuristically decides which functions are simple enough to be worth
    integrating in this way.

    If all calls to a given function are integrated, and the function is
    declared static, then the function is normally not output as assembler
    code in its own right.

    Enabled at level -O3.

    -finline-limit=n
    By default, GCC limits the size of functions that can be inlined.
    This flag allows coarse control of this limit. n is the size of functions
    that can be inlined in number of pseudo instructions.

    Inlining is actually controlled by a number of parameters, which may
    be specified individually by using --param name=value. The -finline-
    limit=n option sets some of these parameters as follows:

    max-inline-insns-single
    is set to n/2.
    max-inline-insns-auto
    is set to n/2.

    ....

    --
    Lionel B
    Lionel B, Jul 8, 2008
    #12
  13. Rares Vernica

    Daniel T. Guest

    On Jul 7, 3:23 pm, Rares Vernica <> wrote:
    > Hello,
    >
    > I have a strange problem.
    >
    > I compile my code with g++ (GCC) 4.1.2. My code runs just fine if I use
    > the -O2 optimization flag. valgrind does not report any memory leak.
    >
    > When I use the -O3 flag, everything falls apart. The program reports
    > Segmentation fault. valgrind reports some Invalid read.
    >
    > Moreover, if I cout something near the line for which valgrind reports
    > the invalid read, then everything works fine, no more segmentation faults
    > or invalid reads.


    Before you follow Gianni's advice, make sure you have initialized
    *every* variable, especially pointers.
    Daniel T., Jul 8, 2008
    #13
  14. Rares Vernica

    Mirco Wahab Guest

    Rares Vernica wrote:
    > I compile my code with g++ (GCC) 4.1.2. My code runs just fine if I use
    > the -O2 optimization flag. valgrind does not report any memory leak.
    >
    > When I use the -O3 flag, everything falls apart. The program reports
    > Segmentation fault. valgrind reports some Invalid read.


    I had a similar problem when using -O3 in connection
    with -fomit-frame-pointer. Boost_Regex would just
    segfault on some occasions.

    Removed -fomit-frame-pointer and all was fine
    (this was gcc 4.2.3 IIRC).

    Regards

    M.
    Mirco Wahab, Jul 8, 2008
    #14
  15. Rares Vernica

    James Kanze Guest

    On Jul 8, 12:32 am, Rares Vernica <> wrote:
    > Rares Vernica <> writes:
    > > I compile my code with g++ (GCC) 4.1.2. My code runs just
    > > fine if I use the -O2 optimization flag. valgrind does not
    > > report any memory leak.


    > > When I use the -O3 flag, everything falls apart. The program
    > > reports Segmentation fault. valgrind reports some Invalid
    > > read.


    > > Moreover, if I cout something near the line for which
    > > valgrind reports the invalid read, then everything works
    > > fine, no more segmentation faults or invalid reads.


    > It was a bug in my code. :( Now it works fine with -O3.


    > Still, I am a little bit confused how the bug generated a
    > segmentation fault only with -O3.


    The generated code will be different according to the
    optimization level. What the differences may be, we can only
    speculate, not having seen your code, nor knowing what error
    you'd made.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Jul 8, 2008
    #15
  16. On Jul 7, 7:32 pm, Rares Vernica <> wrote:
    > Rares Vernica <> writes:
    > > I compile my code with g++ (GCC) 4.1.2. My code runs just fine if I use
    > > the -O2 optimization flag. valgrind does not report any memory leak.

    >
    > > When I use the -O3 flag, everything falls apart. The program reports
    > > Segmentation fault. valgrind reports some Invalid read.

    >
    > > Moreover, if I cout something near the line for which valgrind reports
    > > the invalid read, then everything works fine, no more segmentation faults
    > > or invalid reads.

    >
    > It was a bug in my code. :( Now it works fine with -O3.
    >
    > Still, I am a little bit confused how the bug generated a segmentation
    > fault only with -O3.
    >
    > Thanks.
    > Rares


    what was the bug?
    Diego Martins, Jul 8, 2008
    #16
  17. Diego Martins <> writes:

    > On Jul 7, 7:32 pm, Rares Vernica <> wrote:
    >> Rares Vernica <> writes:
    >> > I compile my code with g++ (GCC) 4.1.2. My code runs just fine if I use
    >> > the -O2 optimization flag. valgrind does not report any memory leak.

    >>
    >> > When I use the -O3 flag, everything falls apart. The program reports
    >> > Segmentation fault. valgrind reports some Invalid read.

    >>
    >> > Moreover, if I cout something near the line for which valgrind reports
    >> > the invalid read, then everything works fine, no more segmentation faults
    >> > or invalid reads.

    >>
    >> It was a bug in my code. :( Now it works fine with -O3.
    >>
    >> Still, I am a little bit confused how the bug generated a segmentation
    >> fault only with -O3.
    >>
    >> Thanks.
    >> Rares

    >
    > what was the bug?


    The bug was related to the number of processing steps required to
    produce the results. Because I was updating some counters incorrectly,
    the algorithm had to do more steps to produce the results. Still, the
    results were correct, but the code was less efficient.

    Nevertheless, the processing steps should all be within correct memory
    bounds.

    Thanks.
    Rares
    Rares Vernica, Jul 9, 2008
    #17
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Alex Hunsley
    Replies:
    17
    Views:
    863
  2. Pud
    Replies:
    0
    Views:
    573
  3. Replies:
    0
    Views:
    525
  4. Ivan Vecerina
    Replies:
    0
    Views:
    482
    Ivan Vecerina
    Jun 29, 2003
  5. Vasileios Zografos

    Re: segmentation fault exception handling

    Vasileios Zografos, Jun 30, 2003, in forum: C++
    Replies:
    5
    Views:
    15,593
    Pete Becker
    Jul 1, 2003
Loading...

Share This Page