https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86138
--- Comment #6 from Christian Franke <franke at computer dot org> --- (In reply to Jonathan Wakely from comment #4) > Could you please debug this to find where it's crashing and why? It segfaults with a bogus pointer below std::string::_Rep::_M_dispose(). A comparison of assembly output and object file symbols leads to the root of the problem: 1) -std=c++14: string::string() and getline() are called from cygstdc++6.dll. OK. 2) -std=c++17: getline() is called from cygstdc++6.dll. All code for string::string() is part of the executable. The empty string is initialized with the static std::string::_Rep::_S_empty_rep_storage[] from the executable. But getline() uses the string() implementation from the DLL which checks against the DLL version of _S_empty_rep_storage[] here: _M_dispose(const _Alloc& __a) _GLIBCXX_NOEXCEPT { #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0 if (__builtin_expect(this != &_S_empty_rep(), false)) #endif { ... } This finally results in a bogus delete[] of the _S_empty_rep_storage[] from the executable. 2) -std=c++17 -static: The linker does not pull another _S_empty_rep_storage[] from the static library because it already exists in the object file. OK. This version of the testcase does not crash because _S_empty_rep_storage[] is not used: int main() { std::string line("x"); std::istringstream stream("*"); std::getline(stream, line, '\n'); return (int)line.c_str()[0]; }