g++ -O2 OK, -O3 Segmentation fault

R

Rares Vernica

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
 
G

Gianni Mariani

Rares said:
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
 
J

Johannes Bauer

Gianni said:
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
 
R

Rares Vernica

Rares Vernica said:
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
 
I

Ian Collins

Rares said:
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?
 
J

James Kanze

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

Michael DOUBEZ

Rares Vernica a écrit :
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.
 
J

Juha Nieminen

Rares said:
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).
 
L

Lionel B

Rares Vernica a écrit :

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

Michael DOUBEZ

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

Lionel B

Lionel B a écrit :

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.

....
 
D

Daniel T.

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

Mirco Wahab

Rares said:
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.
 
J

James Kanze

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

Diego Martins

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?
 
R

Rares Vernica

Diego Martins said:
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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top