-
Notifications
You must be signed in to change notification settings - Fork 303
PIE+LTO causes Bitcoin-Qt to segfault at startup #867
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
To be clear, the actual issue is that cmake has POSITION_INDEPENDENT_CODE, which claims to implement PIC, but it does not. It enables PIE instead, which is not what you actually asked for, and they are unfortunately different enough to matter. It's quite fine to enforce -fPIC (and also to link with -pie), but cmake simply does not provide the necessary builtin functionality to do it correctly. |
This suggests the issue may be specific to the default compiler options. If so, please consider updating the OP accordingly.
|
Ubuntu builds their Qt with "reduce relocations" disabled, so it doesn't hit this (see https://bugs.gentoo.org/933110#c5). The root cause is a mix between Qt, CMake, and the fact there's no way for the toolchain to communicate a problem. CMake doesn't seem particularly interested in fixing it given https://gitlab.kitware.com/cmake/cmake/-/issues/15570#note_477736. Qt says that the right thing to do is to honour their own recommendation (naturally). I spent a significant amount of time investigating it and I really don't see an option besides changing CMake (and CMake doesn't seem interested) than fixing upstream projects which use Qt to simply not use |
I remember us already having code to work around something similar to this. i.e: https://github.com/bitcoin/bitcoin/blob/dbc450c1b59b24421ba93f3e21faa8c673c0df4c/build-aux/m4/bitcoin_qt.m4#L182? Looks like it was just dropped, rather than ported to CMake? |
Was it related to LTO? |
It's the same problem. It just shows up worse with LTO because Qt's sanity check can't fire to tell you (at the point where the preprocessor is run, the right flags are in effect) and give you a build failure instead. The way that CMake handles this (which is buggy, at least for Qt) means it doesn't show up without LTO, because it does pass |
Is anyone aware of other distros that provide shared Qt libraries built with (asking because I'm not quite familiar with Gentoo) Fedora, Debian/Ubuntu, and Arch do not have such an issue. |
Fedora, Debian/Ubuntu, opensuse, Alpine disable it. Arch disables it but only for Qt 5 AFAICT (has it enabled for Qt 6). Looks like Void has it on. |
Building on Arch with |
Interesting! It should happen since https://gitlab.archlinux.org/archlinux/packaging/packages/qt6-base/-/commit/5cd71aed56de955b182e20263a50cd91bf7b6aaa. Thiago gives some ways to check whether it was in effect at https://bugreports.qt.io/browse/QTBUG-112332?focusedId=716976&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-716976. I have an idea which may explain it, let me poke. |
@whitslack @eli-schwartz @thesamesam Setting the required conditions aside, can you confirm whether the following patch resolves the issue on Gentoo: --- a/src/qt/CMakeLists.txt
+++ b/src/qt/CMakeLists.txt
@@ -250,6 +250,8 @@ if(qt_lib_type STREQUAL "STATIC_LIBRARY")
)
endif()
+list(TRANSFORM CMAKE_CXX_LINK_OPTIONS_PIE REPLACE "${CMAKE_CXX_COMPILE_OPTIONS_PIE}" "${CMAKE_CXX_COMPILE_OPTIONS_PIC}")
+
add_executable(bitcoin-qt
main.cpp
../init/bitcoin-qt.cpp ? |
This approach appears suitable for Gentoo's Qt packages as well, since, according to this commit message, the |
@hebasto I can confirm the above resolves the issue. (I am the Gentoo bug reporter on this) |
Yes, this is the conclusion I reached as well. The original Qt commit adding the improved version didn't have it optional, and I saw it referenced in headers which made me think the feature detection had enabled it -- but it only detected it, didn't enable it unless passed explicitly, as a followup Qt commit (a while later) disabled it until newer Binutils is widely adopted, I think. Anyway, you're absolutely right, and it's indeed a fix for us: we're adopting the no-direct-extern-access Qt option which fixes reduce-relocations. I think the fix you mention is right for the reduce-relocations case, though (just that we in Gentoo, and anyone else using reduce-relocations, are best off using that newer feature on top to avoid hitting issues like this). Thank you! |
Issues, reports or feature requests related to the GUI should be opened directly on the GUI repo
Report
When PIE and LTO are combined, Qt applications crash at startup. See Gentoo bug 954171. You can read all the gorey details about the underlying issue (that also affected Wireshark) here. Basically, the issue is that Qt's
qcompilerdetection.h
prohibits building Qt with PIE because PIE breaks a critical assumption that Qt makes, but when a Qt application is built using LTO, the application's-fPIE
flag overrides Qt's-fPIC
flag and causes pieces of Qt to be optimized under the PIE model, which breaks it and causes it to segfault at runtime. The guard inqcompilerdetection.h
is powerless to detect and prevent this because it's implemented by a preprocessor directive, and the preprocessor is not involved during LTO. To fix this, Bitcoin-Qt has to choose either LTO or PIE but not both. In Gentoo we plan to work around this for now by filtering out-flto
from the user's flags, but it would be nicer to have an upstream solution.The text was updated successfully, but these errors were encountered: