folgendes Programm vor:LTO verursacht Absturz in Standardbibliothek
#include <iostream>
#include <string>
int main()
{
std::string s;
std::getline(std::cin, s);
return 0;
}
Ich versuche es mit verschiedenen Flaggen zu bauen und als echo foo | ./prog
laufen.
Wenn ich es mit clang 5.0 oder gcc 7.1 (oder 7.2) mit Optimierung von -O0
bis -O3
erstellen, funktioniert es wie erwartet. Aber wenn ich -flto
auf eine dieser Konfigurationen hinzufügen, stürzt es ab sofort mit der folgenden Backtrace:
/lib64/libc.so.6(+0x721af)[0x7f596b08e1af]
/lib64/libc.so.6(+0x77706)[0x7f596b093706]
/lib64/libc.so.6(+0x78453)[0x7f596b094453]
/usr/lib64/libstdc++.so.6(_ZNSs7reserveEm+0x85)[0x7f596b9ac055]
/usr/lib64/libstdc++.so.6(_ZSt7getlineIcSt11char_traitsIcESaIcEERSt13basic_istreamIT_T0_ES7_RSbIS4_S5_T1_ES4_+0x175)[0x7f596b984c05]
./a.out[0x400d7d]
./a.out[0x400c32]
/lib64/libc.so.6(__libc_start_main+0xf5)[0x7f596b03c6e5]
./a.out[0x400ab9]
Valgrind meldet das gleiche in einer leicht lesbarer Weise:
==30863== Invalid free()/delete/delete[]/realloc()
==30863== at 0x4C2A8DC: operator delete(void*) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==30863== by 0x4F0E054: std::string::reserve(unsigned long) (in /usr/lib64/libstdc++.so.6.0.24)
==30863== by 0x4EE6C04: 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) (in /usr/lib64/libstdc++.so.6.0.24)
==30863== by 0x40091B: main (in /path/to/prog)
==30863== Address 0x6011c0 is 0 bytes inside data symbol "_ZNSs4_Rep20_S_empty_rep_storageE"
Auch funktioniert es OK mit --std=c++14
und darunter sogar mit aktiviertem LTO.
Also, was ist das Problem? Ist es ein Fehler in der LTO-Implementierung für C++ 17 in beiden Compilern? Oder nur die libstdc++
ist mit falschen Flags kompiliert? Ich benutze opensuse 42.3 und die Standardbibliothek wird von den Speichern installiert.
Kann es irgendwie bearbeitet werden?
Vielen Dank für die Antwort! Ihre Links zeigten mir die richtige Richtung, also löste ich das Problem und fügte meine eigene Antwort mit vollständiger Beschreibung hinzu. – Sergey