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

--- Comment #9 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Jonathan Wakely from comment #8)
> The bug is that the symbols in lisbtdc++.so are attempting to delete the
> _S_empty_rep_storage object, which suggests that this check is false when it
> should be true:
> 
>   this != &_S_empty_rep()
> 
> That suggests we have multiple definitions of the empty rep symbol, which
> aren't being combined.

Confirmed by making the following change and rebuilding the library:

--- a/libstdc++-v3/include/bits/basic_string.h
+++ b/libstdc++-v3/include/bits/basic_string.h
@@ -3157,6 +3157,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
          // _S_empty_rep_storage is never modified and the punning should
          // be reasonably safe in this case.
          void* __p = reinterpret_cast<void*>(&_S_empty_rep_storage);
+         __builtin_printf("%p\n", __p);
          return *reinterpret_cast<_Rep*>(__p);
        }

This produces two different addresses, the first one is the address of the
empty rep in the main function, the others are the address inside libstdc++.so
(where the delete happens):

0x6023c0
0x7fe314376100
0x7fe314376100
0x7fe314376100
=================================================================
==29064==ERROR: AddressSanitizer: attempting free on address which was not
malloc()-ed: 0x0000006023c0 in thread T0
    #0 0x7fe314457fd0 in operator delete(void*) (/lib64/libasan.so.4+0xe0fd0)
    #1 0x7fe3140ba291 in __gnu_cxx::new_allocator<char>::deallocate(char*,
unsigned long)
/home/jwakely/src/gcc/build/x86_64-pc-linux-gnu/libstdc++-v3/include/ext/new_allocator.h:125
    #2 0x7fe3140b9745 in std::string::_Rep::_M_destroy(std::allocator<char>
const&)
/home/jwakely/src/gcc/build/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/basic_string.tcc:899
    #3 0x7fe3140b96f7 in std::string::_Rep::_M_dispose(std::allocator<char>
const&)
/home/jwakely/src/gcc/build/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/basic_string.h:3252
    #4 0x7fe3140b635f in std::string::reserve(unsigned long)
/home/jwakely/src/gcc/build/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/basic_string.tcc:961
    #5 0x7fe3140b6c9a in std::string::push_back(char)
/home/jwakely/src/gcc/build/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/basic_string.h:4239
    #6 0x7fe3140b66a6 in std::string::operator+=(char)
/home/jwakely/src/gcc/build/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/basic_string.h:4090
    #7 0x7fe31408891f in std::basic_istream<char, std::char_traits<char> >&
std::getline<char, std::char_traits<char>, std::allocator<char>
>(std::basic_istream<char, std::char_traits<char> >&, std::basic_string<char,
std::char_traits<char>, std::allocator<char> >&, char)
/home/jwakely/src/gcc/gcc/libstdc++-v3/src/c++98/istream-string.cc:168
    #8 0x40106a in main (/tmp/a.out+0x40106a)
    #9 0x7fe3136ec509 in __libc_start_main (/lib64/libc.so.6+0x20509)
    #10 0x401389 in _start (/tmp/a.out+0x401389)

0x0000006023c0 is located 0 bytes inside of global variable
'_S_empty_rep_storage' defined in
'/home/jwakely/gcc/8/include/c++/8.0.0/bits/basic_string.tcc:506:5' (0x6023c0)
of size 32
SUMMARY: AddressSanitizer: bad-free (/lib64/libasan.so.4+0xe0fd0) in operator
delete(void*)
==29064==ABORTING

Reply via email to