GCC optimizer removes necessary code

Bug #817768 reported by kornelix
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
gcc-4.5 (Ubuntu)
New
Undecided
Unassigned

Bug Description

GCC 4.5.2 in Ubuntu 11.04

The program below crashes when compiled with GCC 4.5.2 with optimization
level -O3. This is apparently a bug in GCC.

The crash does not occur if the program is compiled with an earlier
release of GCC, also with -O3 optimization.

The crash does not occur if the program is compiled without optimization.

The crash does not occur if a do-nothing line of code is added which
makes a reference to the variable involved. Apparently this stops GCC
from optimizing-out necessary code.

Crash matrix

GCC level Optimization dummy code result
4.4.5 -O3 no OK
4.5.2 -O0 no OK
4.5.2 -O3 no crash
4.5.2 -O3 yes OK

There is the crash report from GDB:

Program received signal SIGSEGV, Segmentation fault.
0x0000000000498051 in pvlist_remove (pv=0x306b6fc, ii=<value optimized out>) at zfuncs.cc:1774
1774 pv->list[ii-1] = pv->list[ii];
(gdb) q

Here is the relevant part of the program. The commented line will never
execute the printf() call but it does stop the program from crashing.

struct pvlist {
   int max; // max. entries
   int act; // actual entries
   char **list; // entries
};

pvlist * pvlist_create(int max); // create pvlist
void pvlist_free(pvlist *pv); // free pvlist
int pvlist_append(pvlist *pv, cchar *entry, int unique = 0); // append new entry (opt. if unique)
int pvlist_prepend(pvlist *pv, cchar *entry, int unique = 0); // prepend new entry (opt. if unique)
int pvlist_find(pvlist *pv, cchar *entry); // find entry by name
int pvlist_remove(pvlist *pv, cchar *entry); // remove entry by name
int pvlist_remove(pvlist *pv, int Nth); // remove entry by number (0...)
int pvlist_count(pvlist *pv); // return entry count
int pvlist_replace(pvlist *pv, int Nth, cchar *entry); // replace Nth entry (0...)
char * pvlist_get(pvlist *pv, int Nth); // return Nth entry (0...)
int pvlist_sort(pvlist *pv); // sort list, ascending

// remove an entry by number and repack list

int pvlist_remove(pvlist *pv, int ii)
{
   if (ii < 0 || ii >= pv->act) return -1;
   zfree(pv->list[ii]);
   for (ii++; ii < pv->act; ii++) {
      if (! pv->act) printf("meaningless reference %d",ii); // get around GCC optimization bug
      pv->list[ii-1] = pv->list[ii];
   }
   pv->act--;
   return 0;
}

ProblemType: Bug
DistroRelease: Ubuntu 11.04
Package: gcc 4:4.5.2-1ubuntu3
ProcVersionSignature: Ubuntu 2.6.38-10.46-generic 2.6.38.7
Uname: Linux 2.6.38-10-generic x86_64
NonfreeKernelModules: nvidia
Architecture: amd64
Date: Fri Jul 29 00:00:30 2011
InstallationMedia: Ubuntu 11.04 "Natty Narwhal" - Release amd64 (20110427.1)
ProcEnviron:
 LANGUAGE=en_US:en
 LANG=en_US.UTF-8
 SHELL=/bin/bash
SourcePackage: gcc-defaults
UpgradeStatus: No upgrade log present (probably fresh install)

Revision history for this message
kornelix (mikecorn-deactivatedaccount) wrote :
Revision history for this message
kornelix (mikecorn-deactivatedaccount) wrote :

Sorry the formatting got destroyed.
It would be better if you used a monospace font for this.

Revision history for this message
Matthias Klose (doko) wrote :

- please recheck with GCC 4.5 and GCC 4.6 in oneiric.
- please attach a self-contained example, including the command options used
- include the warnings building the file.

Changed in gcc-defaults (Ubuntu):
status: New → Incomplete
Revision history for this message
kornelix (mikecorn-deactivatedaccount) wrote : Re: [Bug 817768] Re: GCC optimizer removes necessary code

I tried to make a small stand-alone test but the test program always worked. The problem is more involved. Of course my first suspicion was corruption of memory coming from somewhere else in my program, but this seems ruled out by the fact that it works fine without optimization and it works fine when I added the dummy code to reference the variable (ii) whose code was getting removed. This is all explained in the original report. My tabular formatting was removed by the bug report utility so it has to be looked at more carefully.

There were no compiler warnings.

I will try the tests with 4.5 and 4.6 tomorrow.

On 08/08/2011 03:21 PM, Matthias Klose wrote:
> - please recheck with GCC 4.5 and GCC 4.6 in oneiric.
> - please attach a self-contained example, including the command options used
> - include the warnings building the file.
>
> ** Changed in: gcc-defaults (Ubuntu)
> Status: New => Incomplete
>

Revision history for this message
kornelix (mikecorn-deactivatedaccount) wrote :

I conducted these experiments and here are the results:
+ GCC 4.4.5 in Ubuntu 10.04: NO BUG
+ GCC 4.5.2 in Ubuntu 11.04: BUG PRESENT
+ GCC 4.6.1 in Ubuntu 11.10 (alpha 3): NO BUG

Other factors:
+ The bug goes away if optimization is -O0 instead of -O3
+ The bug goes away if a do-nothing line of code is inserted to reference the variable "ii" whose initialization is apparently being removed with -O3 optimization.

I was not able to make a minimal program to demonstrate the bug. The bug went away in the minimal program. Therefore I have attached the full application which demonstrates the bug.

How to demonstrate the bug:
0. Use Ubuntu 11.04 with GCC 4.5.2 and libgtk2.0-dev installed
1. unpack the tarball: $ tar -xzf mashup-2.9.tar.gz
2. build the application: $ cd mashup; $ make
3. run the application: $ ./mashup
4. press the toolbar button with the printer icon (3rd from last)
5. choose the last "paper format" in the drop-down list: "custom N.N x N.N cm"
6. edit this item by deleting characters from the end.
This should be permitted with no crashing.
7. $ gedit zfuncs.cc
8. search for "////".
This is a line in the function pvlist_remove(), commented "stop g++ optimization bug".
This is a do-nothing line of code whose purpose is to reference the variable "ii".
Make sure you are in pvlist_remove() since "////" is present in a few other places.
9. comment this line away by adding "//" before the line
10. rebuild: $ make clean; $ make
11. repeat steps 3-6. After deleting two characters, the program crashes with seg-fault
12. $ gedit Makefile
13. replace the GCC optimization -O3 with -O0
14. repeat steps 3-6. The bug is gone.

There is another instance of this bug in another function, image_navi::image_navigate(). See the line of code in that function containing the comment "stop g++ optimization bug". This is an unrelated function demonstrating the same bug, but testing in this case is more complex.

On 08/08/2011 03:21 PM, Matthias Klose wrote:
> - please recheck with GCC 4.5 and GCC 4.6 in oneiric.
> - please attach a self-contained example, including the command options used
> - include the warnings building the file.
>
> ** Changed in: gcc-defaults (Ubuntu)
> Status: New => Incomplete
>

Revision history for this message
kornelix (mikecorn-deactivatedaccount) wrote :

Woops. Here is the attachment

On 08/08/2011 03:21 PM, Matthias Klose wrote:
> - please recheck with GCC 4.5 and GCC 4.6 in oneiric.
> - please attach a self-contained example, including the command options used
> - include the warnings building the file.
>
> ** Changed in: gcc-defaults (Ubuntu)
> Status: New => Incomplete
>

Revision history for this message
kornelix (mikecorn-deactivatedaccount) wrote :
Revision history for this message
Matthias Klose (doko) wrote :

- what happens with gcc-4.5.3 from oneiric?
- does lowering the optimization level to -O2 or -O1 enough to avoid the issue?

Revision history for this message
kornelix (mikecorn-deactivatedaccount) wrote :

Additional information using GCC 4.5.2 in Ubuntu 11.04:
Optimization -O3: bug present
Optimization -O2 or less: no bug

Revision history for this message
kornelix (mikecorn-deactivatedaccount) wrote :

Using Ubuntu 11.10 (alpha 3) I was unable to install GCC 4.5.3 together with libgtk2.0-dev. Synaptic failed, also after installing all current updates.

Note that enough information was provided above for anyone to make these kinds of tests without big time and effort.

Revision history for this message
Launchpad Janitor (janitor) wrote :

[Expired for gcc-defaults (Ubuntu) because there has been no activity for 60 days.]

Changed in gcc-defaults (Ubuntu):
status: Incomplete → Expired
Revision history for this message
kornelix (mikecorn-deactivatedaccount) wrote :

Good way to get rid of bugs - ignore until they expire.

Revision history for this message
Matthias Klose (doko) wrote :

bug robots don't know about sarcasm

Changed in gcc-defaults (Ubuntu):
status: Expired → New
affects: gcc-defaults (Ubuntu) → gcc-4.5 (Ubuntu)
Revision history for this message
kornelix (mikecorn-deactivatedaccount) wrote :

I have found another similar case where adding a meaningless reference to a variable within a loop caused a crash to go away.
This time it is gcc 4.6.1 in Ubuntu 11.10. I have now found this bug 3 times in 3 different programs in the past. All 3 cases were similar loops to the one below, with the same "fix": add a do-nothing line of code.

SUMMARY
gcc 4.5.2 optimization O3 NO BUG
gcc 4.6.1 optimization O2 NO BUG
gcc 4.6.1 optimization O3 CRASH
gcc 4.6.1 optimization O3 with dummy reference added NO BUG

Here is the loop with the dummy reference included:

      for (kk = ap; kk < sd->nap[spc]; kk++) {
          if (! kk) printf("meaningless reference %d",kk); // stop gcc optimization bug
          sd->apx[spc][kk] = sd->apx[spc][kk+1];
          sd->apy[spc][kk] = sd->apy[spc][kk+1];
      }

The backtrace made no sense. The crash was a seg fault in a function not being called.

Revision history for this message
Václav Šmilauer (eudoxos) wrote :

Has this bug been reported to gcc developers? In that case, it can be tracked automatically.

Revision history for this message
kornelix (kornelix) wrote :

I reported it years ago and never heard anything. I don't even know if the
bug is still there in more recent releases of gcc. Once I recognized the
problem, it was easy to get around by adding do-nothing statements to
reference variables whose code was getting optimized out. I also tried to
make a small test case to illustrate the problem but this test always
worked OK.

If you delete the bug from Ubuntu tracking that is OK with me.

regards
Mike

2012/3/6 Václav Šmilauer <email address hidden>

> Has this bug been reported to gcc developers? In that case, it can be
> tracked automatically.
>
> --
> You received this bug notification because you are subscribed to the bug
> report.
> https://bugs.launchpad.net/bugs/817768
>
> Title:
> GCC optimizer removes necessary code
>
> To manage notifications about this bug go to:
>
> https://bugs.launchpad.net/ubuntu/+source/gcc-4.5/+bug/817768/+subscriptions
>

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.