https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80149

            Bug ID: 80149
           Summary: segfault in std::vector::resize when mixing binaries
                    from gcc4 and gcc5 on armhf
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: klug.stefan at gmx dot de
  Target Milestone: ---

Created attachment 41017
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=41017&action=edit
Minimal sample and intermediate files

Hi everyone,

I came across a segfault on armhf where i suspect it might be an optimizer
issue.

What triggers the bug:
- A .so, compiled with gcc-4.x and -O2 using vector<long long>::resize()
- A binary compiled with gcc 5, also using vector<long long>::resize()
- at least one of the two binaries compiled with -O2
- The binary calls the lib resulting in a segfault

I've attached a minimal sample to this report. I reproduced the problem on
ubuntu 16.04 armhf.
To reproduce the crash run ./build.sh && ./sample
I also left the intermediate files and a build.log in the archive.
Additionally there is a docker receipe ( ./show-using-docker.sh ) included
which reproduces the bug using qemu (although this is of limited help as gdb
doesn't work with qemu-user-static)


The stack trace:
#0  __libc_do_syscall () at ../sysdeps/unix/sysv/linux/arm/libc-do-syscall.S:47
#1  0xb6dc7648 in __GI_raise (sig=sig@entry=6) at
../sysdeps/unix/sysv/linux/raise.c:54
#2  0xb6dc834a in __GI_abort () at abort.c:89
#3  0xb6f27ad2 in __gnu_cxx::__verbose_terminate_handler() () from
/usr/lib/arm-linux-gnueabihf/libstdc++.so.6
#4  0xb6f26330 in ?? () from /usr/lib/arm-linux-gnueabihf/libstdc++.so.6
#5  0xb6f26386 in std::terminate() () from
/usr/lib/arm-linux-gnueabihf/libstdc++.so.6
#6  0xb6f265aa in __cxa_throw () from
/usr/lib/arm-linux-gnueabihf/libstdc++.so.6
#7  0xb6f41300 in std::__throw_length_error(char const*) () from
/usr/lib/arm-linux-gnueabihf/libstdc++.so.6
#8  0x0001148c in std::vector<long long, std::allocator<long long>
>::_M_check_len (this=0xbefff4b8, __n=3204445360, __s=0x11a34
"vector::_M_fill_insert") at /usr/include/c++/5/bits/stl_vector.h:1425
#9  0x00011176 in std::vector<long long, std::allocator<long long>
>::_M_fill_insert (this=0xbefff4b8, __position=<error reading variable: Cannot
access memory at address 0x64>, __n=3204445360, 
    __x=@0x0: <error reading variable>) at
/usr/include/c++/5/bits/vector.tcc:489
#10 0xb6fc5b82 in std::vector<long long, std::allocator<long long> >::insert
(__x=@0xbefff4b0: 0, __n=100, __position=..., this=0xbefff4b8) at
/usr/include/c++/4.9/bits/stl_vector.h:1073
#11 std::vector<long long, std::allocator<long long> >::resize (__x=0,
__new_size=100, this=0xbefff4b8) at /usr/include/c++/4.9/bits/stl_vector.h:716
#12 libfoo::do_something () at libfoo.cpp:9
#13 0x00010c56 in main () at sample.cpp:11

My analysis so far:
- c++/.../bits/vector.tcc marks all symbols with _GLIBCXX_VISIBILITY(default),
so they are exported from a .so using them. I therefore assumed that these
symbols (vector<>::_M_fill_insert etc.)  belong to the public interface of the
libstdc++ and are backwards compatible. Is this assumption correct?
- All these symbols get weak linkage and the sample app also exports them (this
time the version of gcc5)
- At runtime the linker merges the weak symbols and "injects" the gcc5 version
into the .so calls. You can see that in the stack trace where vector::resize is
the last symbol from c++/4.9/bits bits.
- Somehow the parameter to _M_fill_insert is messed up, although the signature
of the function didn't change from gcc 4 to 5.
- Thats the point where I'm lost. 

I couldn't reproduce the issue on x86.

Kind regards,
Stefan

Reply via email to