This is the mail archive of the gcc@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]

Re: GCC 4.9.2 -O3 gives a seg fault / GCC 4.8.2 -O3 works


On 2015.01.06 at 03:18 -0500, Paul Smith wrote:
> Hi all.  It's possible my code is doing something illegal, but it's also
> possible I've found a problem with -O3 optimization in GCC 4.9.2.  I've
> built this same code with GCC 4.8.2 -O3 on GNU/Linux and it works fine.
> It also works with GCC 4.9.2 with lower -O (-O2 for example).
> 
> When I try a build with GCC 4.9.2 -O3 I'm seeing a segfault, because we
> get confused and invoke code that we should be skipping.
> 
> I've compressed the test down to a self-contained sample file that I've
> attached here.  Save it and run:
> 
>   g++-4.9.2 -g -O3 -o mystring mystring.cpp
> 
> Then:
> 
>   ./mystring
>   Segmentation fault
> 
> You can also add -fno-strict-aliasing etc. and it doesn't make any
> difference.
> 
> The seg fault happens in the implementation of operator +=() where we're
> appending to an empty string, so this->data is NULL.  That method starts
> like this (after the standard pushes etc.):
> 
>    0x0000000000400a51 <+17>:    mov    (%rdi),%r14
> 
> which puts this->data (null) into %r14.  Later on, with no intervening
> reset of r14, we see this:
> 
>    0x0000000000400ac5 <+133>:   cmp    %r12,%r14
>    0x0000000000400ac8 <+136>:   je     0x400b18 <String::operator+=(char const*)+216>
>    0x0000000000400aca <+138>:   subl   $0x1,-0x8(%r14)
> 
> We don't take the jump, and this (+138) is where we get the segfault
> because r14 is still 0.  This is in the if-statement in the release()
> method where it subtracts 1 from count... but it should never get here
> because this->data (r14) is NULL!
> 
>   (gdb) i r rip
>   rip            0x400aca 0x400aca <String::operator+=(char const*)+138>
>   (gdb) i r r14
>   r14            0x0      0
> 
> Anyone have any thoughts about this?  I know the inline new/delete is
> weird but it's required to repro the bug, and we need our own new/delete
> because we're using our own allocator.

gcc-help is more appropriate for this kind of question.

If you compile with gcc-5 and -fsanitize=undefined you'll get:

mystring.cpp:104:26: runtime error: null pointer passed as argument 2, which is declared to never be null

So you should guard the memcpy() call.

-- 
Markus


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