From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 1679 invoked by alias); 22 Mar 2007 04:24:59 -0000 Received: (qmail 1645 invoked by uid 48); 22 Mar 2007 04:24:42 -0000 Date: Thu, 22 Mar 2007 04:24:00 -0000 Subject: [Bug c++/31309] New: g++ 4.2.0 amd64 codegen issue with -O0. 6 byte assignment at end of structure reads/writes past end of structure causing SEGV when that memory is not accessable. X-Bugzilla-Reason: CC Message-ID: Reply-To: gcc-bugzilla@gcc.gnu.org To: gcc-bugs@gcc.gnu.org From: "peeterj at ca dot ibm dot com" Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org X-SW-Source: 2007-03/txt/msg02101.txt.bz2 Description: Code includes two structures, a 6 byte struct of the following form: struct 6bytes { char [2] ; char [4] } and another that embeds this at the very end in the following form: struct { bool ; bool ; 6bytes } ;f compiler is generating code for assignment to the trailing 6byte struct using an 8 byte read from that address, then merging in the value to be assigned, and finally writing back 8 bytes. If this structure is allocated from memory where this 8 byte sequence is not accessable (ie: at the end of a shmat memory region for example), this results in a trap. When the memory is accessable the compiler generated code does happen to retain the value that follows the structure being accessed, but even if the 2 bytes of memory trailing the structure is accessable, this generated code that modified memory outside of the structure is not thread safe. This has been observed with GCC 4.2 prerelease compilers, but not GCC 3.3.3. I don't know if the issue applies to 4.1 or 4.0 compilers too. host/target/build triplets provided above. Other info: >Release: gcc (GCC) 4.2.0 20070317 (prerelease) >Environment: System: Linux hotel09 2.6.5-7.191-smp #1 SMP Tue Jun 28 14:58:56 UTC 2005 x86_64 x86_64 x86_64 GNU/Linux Architecture: x86_64 configured with: ../gcc-4.2.0-20070316/configure --prefix=/vbs/bldsupp.linux1/linuxamd64/gcc-4.2.0-20070316 --enable-threads=posix --enable-languages=c,c++ --enable-shared --enable-__cxa_atexit >How-To-Repeat: Sample code will be attached. This forces the memory following the structure to be unreadable by calling mprotect. Build command of the form: /view/peeterj_gcc-4.2.0-20070316-decfloat/vbs/bldsupp/linuxamd64/gcc-4.2.0/bin/g++ -O0 x.C -Wl,-rpath,/view/peeterj_gcc-4.2.0-20070316-decfloat/vbs/bldsupp/linuxamd64/gcc-4.2.0/lib64 -o ./xx (-rpath gunk is because I don't have the runtime locally installed) The following gdb session demonstrates the issue (but will make more sense when looking at the code). hotel09:/vbs/engn/squ> gdb x GNU gdb 6.3 Copyright 2004 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "x86_64-suse-linux"...Using host libthread_db library "/lib64/tls/libthread_db.so.1". (gdb) run Starting program: /vbs/engn/squ/x [Thread debugging using libthread_db enabled] [New Thread 183048206464 (LWP 18902)] Program received signal SIGSEGV, Segmentation fault. [Switching to Thread 183048206464 (LWP 18902)] 0x0000000000400edf in XXX::Initialize (this=0x7fbfff8ff8, iIndex=0) at x.C:51 51 pDictRidderInfo->dRID = INIT_6_BYTES_ZERO(); (gdb) disassemble $rip $rip+30 Dump of assembler code from 0x400edf to 0x400efd: 0x0000000000400edf <_ZN3XXX10InitializeEi+71>: mov 0xa(%rbx),%rcx 0x0000000000400ee3 <_ZN3XXX10InitializeEi+75>: mov %rcx,0xffffffffffffffd0(%rbp) 0x0000000000400ee7 <_ZN3XXX10InitializeEi+79>: movzbq %dl,%rcx 0x0000000000400eeb <_ZN3XXX10InitializeEi+83>: mov 0xffffffffffffffd0(%rbp),%rdx 0x0000000000400eef <_ZN3XXX10InitializeEi+87>: mov $0x0,%dl 0x0000000000400ef1 <_ZN3XXX10InitializeEi+89>: or %rcx,%rdx 0x0000000000400ef4 <_ZN3XXX10InitializeEi+92>: mov %rdx,0xffffffffffffffd0(%rbp) 0x0000000000400ef8 <_ZN3XXX10InitializeEi+96>: mov 0xffffffffffffffd0(%rbp),%rdx 0x0000000000400efc <_ZN3XXX10InitializeEi+100>: mov %rdx,0xa(%rbx) End of assembler dump. (gdb) p $rbx $1 = 548682059760 (gdb) p (void*)$rbx+0xa+6 $2 = (void *) 0x7fbfffd000 >Fix: Enabling optimization -O2 works around the issue, but the builds that we want to do with gcc-4.2 are development (-g) builds so -O isn't a natural fit. -- Summary: g++ 4.2.0 amd64 codegen issue with -O0. 6 byte assignment at end of structure reads/writes past end of structure causing SEGV when that memory is not accessable. Product: gcc Version: 4.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: peeterj at ca dot ibm dot com GCC build triplet: x86_64-unknown-linux-gnu GCC host triplet: x86_64-unknown-linux-gnu GCC target triplet: x86_64-unknown-linux-gnu http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31309