This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug optimization/15295] New: Instruction scheduling with -O2 on i686 creates fatal aliasing bug


I believe to have found a C++ program for which optimized (-O2) compilation
on an i686 machine by combination of function inlining and out-of-order
instruction scheduling leads to assembler code in which two registers point
to the same piece of memory in two different roles, and accesses to it are
performed in the wrong order, leading to a crash in the code.

I couldn't find an earlier bug report subsuming my problem.

I tried but failed to construct a small example; apparently the problem
depends on a large context. I have attached a single preprocessed source
file resched_aliasing.ii (1.2 MB) which was created by
$ g++-3.3.3 -Wno-deprecated -O2 -Wall -g -c resched_aliasing.C -E -o
resched_aliasing.ii -I(many dirs) -D(some defines)
The errorneous assembler output resched_aliasing.s can be generated with
$ g++-3.3.3 -O2 resched_aliasing.ii -g -S
(I've left out the .s file according to the bug reporting instructions.)
Both invocations of g++ do not generate warnings etc.

The executable created from that code (which requires linking against
several libraries that are irrelevant here) crashes with a SIGSEGV in the
following place (see .s file after label .LBB1256 in line 7695):

( 1) .LBB1256:
( 2)	movl	_ZN4CORE10MemoryPoolINS_9BigRatRepEE7memPoolE, %eax
( 3)	testl	%eax, %eax
( 4)	jne	.L2368
     (jump is taken)
( 5)	...
( 6) .L2368:
( 7)	decl	_ZN4CORE10MemoryPoolINS_9BigRatRepEE7memPoolE+4
( 8)	movl	%eax, %ebx
( 9)	movl	-40(%ebp), %edi
(10)	movl	$1, (%ebx)
(11)	movl	(%eax), %eax

This code is a mixture of a MemoryPool, maintaining a linked list of
uninitialized or destroyed BigRatRep objects, and the constructor of
BigRatRep's base class RCRepImpl, which initializes the refCount member
varible at offset 0 to the value 1.

The relevant source code lines are these:

(.ii file, around line 34719)
template<class T>
class MemoryPool {
  // ...
  void* allocate(size_t) {
    if (next == __null)
      expandFreeList();
    MemoryPool<T> *head = next;
    next = head->next;
    nCount --;
    return head;
  }
  // ...
};

(.ii file, around line 36991)
template<class Deriving>
class RCRepImpl {
public:
  RCRepImpl() : refCount(1) {}
  // ...
};

In line (2) of the assembler code, the pointer `next' is read into %eax.
It is then checked to be non-zero (lines (3..6)). The decrement of `nCount'
in line (7) and the unrelated line (9) are irrelevant here. The problem is
that in (8) %ebx becomes an alias for %eax, and the initialization of refCount
to 1 in line (9) is scheduled before `next = head->next' takes place in line
(11): now (11) is an access to the illegal address 0x1, causing the segfault.

The problem goes away when compiling without optimization or when making
the allocate() member function non-inline (by giving its definition outside
the class definition).

The incriminated pieces of source code come from the current beta snapshot
of the CORE library. Other parts of the source code come from gmp-4.1.3
and boost-1.30.2 and the yet unreleased EXACUS library project. Their
various open source licenses apply.

I'm using g++-3.3.3 which was configured as follows:
./configure --prefix=/usr/local/gcc-3.3/gcc-3.3.3 --program-suffix=-3.3.3
--enable-languages=c,c++ : (reconfigured) ./configure
--prefix=/usr/local/gcc-3.3/gcc-3.3.3 --program-suffix=-3.3.3
--enable-languages=c,c++ : (reconfigured) ./configure
--prefix=/usr/local/gcc-3.3/gcc-3.3.3 --program-suffix=-3.3.3
--enable-languages=c,c++

Thanks a lot in advance!

-- 
           Summary: Instruction scheduling with -O2 on i686 creates fatal
                    aliasing bug
           Product: gcc
           Version: 3.3.3
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: optimization
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: arno at mpi-sb dot mpg dot de
                CC: gcc-bugs at gcc dot gnu dot org
 GCC build triplet: i686-pc-linux-gnu
  GCC host triplet: i686-pc-linux-gnu
GCC target triplet: i686-pc-linux-gnu


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=15295


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]