LTO는

2017-11-23 2 views
1

는 다음과 같은 프로그램을 고려 표준 라이브러리에서 충돌이 발생합니다.LTO는

-O0에서 -O3까지 최적화 된 clang 5.0 또는 gcc 7.1 (또는 7.2)로 빌드하면 예상대로 작동합니다. 나는 이러한 구성의에 -flto를 추가하는 경우, 그것은 다음과 같은 역 추적 즉시 충돌 :

==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 작동합니다

/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의이 약간 더 읽을 수있는 방식으로 같은보고 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의 링크를 따라, 나는 마지막으로 문제의 원인을 설명 버그 page을, Binutils의에 도착했다.

버그

마침내 바이너리 유틸리티 2.30로 고정하고 2.29과 2.28의 binutils 백 포트 하였다. binutils 2.29로 업데이트하면 테스트 예제가 수정되었지만 실제 빌드는 여전히 영향을 받았습니다.

나는 내 프로젝트의 종속성 중 하나가 (내가 CMake 및 external project module 사용) LTO없이 구축 할 것을 알아 냈다. 적절한 아카이버 모든 종속성 -flto 추가 및 사용 (즉 대신 argcc-ar)의 문제를 완전히 해결했다.