msys2 / MINGW-packages

Package scripts for MinGW-w64 targets to build under MSYS2.
https://packages.msys2.org
BSD 3-Clause "New" or "Revised" License
2.29k stars 1.22k forks source link

GCC 10.2.0-6 with LTO segfaults #8074

Open andrew-aladev opened 3 years ago

andrew-aladev commented 3 years ago

Please refer the following issue on cmake gitlab.

If you tries to enable IPO (GCC LTO) in cmake using mingw-w64-x86_64-gcc version 10.2.0-6, than you executable segfaults.

Please checkout IPO folder with easy project that reproduces the issue.

lazka commented 3 years ago

I can confirm, but no idea. We build CPython with LTO+PGO, so LTO can work with our toolchain.. if that helps.

mati865 commented 3 years ago

You are not exporting symbols in DLL correctly, mingw-w64 can often workaround it by using runtime pseudo relocations but it's fragile.

You should build your DLL with __declspec(dllexport) annotations or pass --export-all-symbols to the linker.

andrew-aladev commented 3 years ago

Thank you, I am going to add decls together with WINDOWS_EXPORT_ALL_SYMBOLS. But segfault is not an user friendly solution, maybe mingw gcc can add linker warning that symbols were not properly exported for windows.

PS previous version of mingw-w64-x86_64-gcc installed by default in appveyor (version <= 10.2.0-5) works perfect, we can view the following log.

andrew-aladev commented 3 years ago

Unfortunately today gcc has critical issue that makes dllexport usage impossible. --export-all-symbols is not possible with cmake, because mingw platform has no CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS in platform file Windows-GNU.cmake. Forcing of set (CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS 1) reveals that it is broken. So for now there is no way to fix lto in mingw. If you want to export inline C99 than mingw LTO won't work.

Suddenly new MSVC with C17 turned out to be not so bad: dllexport works perfect with any data and functions, LTO works fine, hmm...

jtanx commented 3 years ago

This is what we do to export all symbols, it works just fine.

https://github.com/fontforge/fontforge/blob/d867fe0ab9c1edb2a5d268f713b72bef7146d59b/fontforge/CMakeLists.txt#L224

andrew-aladev commented 3 years ago

Unfortunately, -Wl,--export-all-symbols -Wl,--enable-auto-import is not working for current mingw gcc version + LTO. The only one possible option is dllexport/dllimport.

# make
C:/msys64/mingw64/bin/cc.exe -flto -fno-fat-lto-objects -o CMakeFiles/fit.dir/a1.c.obj -c C:/fit1/a1.c
C:/msys64/mingw64/bin/cc.exe -flto -fno-fat-lto-objects -o CMakeFiles/fit.dir/a2.c.obj -c C:/fit1/a2.c
C:/msys64/mingw64/bin/cc.exe -flto -fno-fat-lto-objects -Wl,--export-all-symbols -Wl,--enable-auto-import -shared -o libfit.dll -Wl,--out-implib,libfit.dll.a -Wl,--major-image-version,0,--minor-image-version,0 -Wl,--whole-archive CMakeFiles/fit.dir/objects.a -Wl,--no-whole-archive @CMakeFiles/fit.dir/linklibs.rsp
C:/msys64/mingw64/bin/cc.exe -flto -fno-fat-lto-objects -o CMakeFiles/main.dir/main.c.obj -c C:/fit1/main.c
C:/msys64/mingw64/bin/cc.exe -flto -fno-fat-lto-objects -Wl,--whole-archive CMakeFiles/main.dir/objects.a -Wl,--no-whole-archive -o main.exe -Wl,--out-implib,libmain.dll.a -Wl,--major-image-version,0,--minor-image-version,0 @CMakeFiles/main.dir/linklibs.rsp
./main.exe
Segmentation fault
andrew-aladev commented 3 years ago

-Wl,--export-all-symbols works perfect and you are receiving libfit.dll with exported function. But it is not possible to import it automatically without dllimport. So there are 2 options: -Wl,--export-all-symbols + dllimport or dllexport + dllimport for now.

This bug appeared today, but nobody can guarentee that it won't happen tomorrow. I thought that there are 2 possible export modes: dllexport + dllimport or export all / import all. But there are actually 4 possible export modes: dllexport + dllimport, export all + dllimport, dllexport + import all, export all + import all.

standards

Do you remember this meme? It was wrong: if you have 14 standards and someone tries to add +1 standard than you will receive all combinations between 14 standards and 1 additional standard (turned off and turned on) = 28 standards. If someone tries to add 2 standards (gnu and bsd) than we will receive 56 standards.