2017-11-23 33 views
1

は、次のプログラムを考えてみましょう。LTOは標準ライブラリでクラッシュを引き起こし

-O0から-O3までの最適化を使用してclang 5.0またはgcc 7.1(または7.2)でビルドすると、期待どおりに動作します。しかし、私はこれらの構成のいずれかに-fltoを追加する場合、それは以下のバックトレースですぐにクラッシュ:

/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のは、もう少し読みやすいように、同じことを報告します。

==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" 

また、それは--std=c++14でOK動作しますLTOが有効になっていても下にあります。

だから問題は何ですか?両方のコンパイラでC++ 17のLTO実装のバグですか?または、ちょうどlibstdc++が間違ったフラグでコンパイルされていますか? opensuse 42.3を使用し、標準ライブラリはリポジトリからインストールされます。

どうにかして作業することはできますか?

答えて

1

gccの場合、これはこのバグのようです:https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82172

多くの回避策があります。https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82172#c3を参照してください。そのうちの一つは、-D_GLIBCXX_USE_CXX11_ABI=1を使用することです:

g++ -D_GLIBCXX_USE_CXX11_ABI=1 --std=c++17 -flto prog.cpp 

もここで同じ問題flto crash with gcc7.2参照してください。

+0

ありがとうございました!あなたのリンクは私に正しい方向を示していたので、最終的に問題を解決し、自分の答えを完全な記述で追加しました。 – Sergey

0

ks1322のリンクに続いて、私は最終的にbinutilsバグpageに着いた。 はこの問題の根本を説明している。

バグは最終的にbinutils 2.30で修正され、binutils 2.29と2.28にバックポートされました。 binutils 2.29へのアップデートはテストの例を修正しましたが、私の実際のビルドはまだ影響を受けていました。

私はプロジェクトの依存関係(私はCMakeとexternal project moduleを使用しています)がLTOなしでビルドされていることを知りました。すべての依存ファイルに-fltoを追加し、適切なアーカイバ(arの代わりにgcc-ar)を使用すると、問題は完全に解決されました。

関連する問題