-
Notifications
You must be signed in to change notification settings - Fork 11.8k
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
GCC PR109267: g++ -Og generates empty functions with incorrect FDE; the output doesn't handle exceptions when linked with ld.lld #61434
Comments
@llvm/issue-subscribers-lld-elf |
I wanted to check whether this was related to https://reviews.llvm.org/D143136 which was a .eh_frame modification that isn't in LLVM 15 sadly it didn't make a difference. The only observations I can make in the time I had available:
LLD does not discard these and they remain in the consolidated .eh_frame. Indeed lib.o when compiled by GCC does have .eh_frame entries with a couple of zero address range entries, but clang and gcc-9 (on my system) do not produce these entries. However adding a dummy function to lib.cpp doesn't make these zero address range entries disappear. Looking at the binutils bugzilla after tracing the commit that added those messages brings up https://sourceware.org/bugzilla/show_bug.cgi?id=17447 which states that in some circumstances these empty address ranges can cause an unwinder problem. So it looks like it may be either GCC is wrong to output these empty address ranges or LLD is wrong not to discard them. Given that GCC12 already exists it implies that LLD will need to be able to handle these. I personally won't have any spare time to look at this, hopefully MaskRay will when he is back from break. |
Below are the first few lines of I think .file "lib.cpp"
.text
.Ltext0:
.file 0 "/tmp/c/example/src/build" "../lib.cpp"
.type _ZN5boost6detail7variant22visitation_impl_invokeINS1_14invoke_visitorINS1_15result_wrapper1IZ4testRKNS_7variantINS1_14recursive_flagI5Obj_1EEJ5Obj_2EEEEUlRKT_E_SC_EELb0EEEPKvNSA_18has_fallback_type_EEENSD_11result_typeEiRSD_T0_PNS1_22apply_visitor_unrolledET1_l, @function
_ZN5boost6detail7variant22visitation_impl_invokeINS1_14invoke_visitorINS1_15result_wrapper1IZ4testRKNS_7variantINS1_14recursive_flagI5Obj_1EEJ5Obj_2EEEEUlRKT_E_SC_EELb0EEEPKvNSA_18has_fallback_type_EEENSD_11result_typeEiRSD_T0_PNS1_22apply_visitor_unrolledET1_l:
.LFB3842:
.file 1 "/usr/include/boost/variant/detail/visitation_impl.hpp"
.loc 1 165 1 view -0
.cfi_startproc
.LBB98:
.LBI98:
.file 2 "/usr/include/boost/variant/detail/forced_return.hpp"
.loc 2 35 1 view .LVU1
.loc 2 35 1 is_stmt 0 view .LVU2
.LBE98:
.cfi_endproc
.LFE3842:
.size _ZN5boost6detail7variant22visitation_impl_invokeINS1_14invoke_visitorINS1_15result_wrapper1IZ4testRKNS_7variantINS1_14recursive_flagI5Obj_1EEJ5Obj_2EEEEUlRKT_E_SC_EELb0EEEPKvNSA_18has_fallback_type_EEENSD_11result_typeEiRSD_T0_PNS1_22apply_visitor_unrolledET1_l, .-_ZN5boost6detail7variant22visitation_impl_invokeINS1_14invoke_visitorINS1_15result_wrapper1IZ4testRKNS_7variantINS1_14recursive_flagI5Obj_1EEJ5Obj_2EEEEUlRKT_E_SC_EELb0EEEPKvNSA_18has_fallback_type_EEENSD_11result_typeEiRSD_T0_PNS1_22apply_visitor_unrolledET1_l
.type _ZN5boost6detail7variant15visitation_implIN4mpl_4int_ILi20EEENS1_20visitation_impl_stepINS_3mpl6l_iterINS7_5l_endEEESA_EENS1_14invoke_visitorINS1_15result_wrapper1IZ4testRKNS_7variantINS1_14recursive_flagI5Obj_1EEJ5Obj_2EEEEUlRKT_E_SL_EELb0EEEPKvNSJ_18has_fallback_type_EEENT1_11result_typeEiiRSV_T2_NS3_5bool_ILb1EEET3_PSM_PT0_, @function
_ZN5boost6detail7variant15visitation_implIN4mpl_4int_ILi20EEENS1_20visitation_impl_stepINS_3mpl6l_iterINS7_5l_endEEESA_EENS1_14invoke_visitorINS1_15result_wrapper1IZ4testRKNS_7variantINS1_14recursive_flagI5Obj_1EEJ5Obj_2EEEEUlRKT_E_SL_EELb0EEEPKvNSJ_18has_fallback_type_EEENT1_11result_typeEiiRSV_T2_NS3_5bool_ILb1EEET3_PSM_PT0_:
.LFB3844:
.loc 1 184 1 is_stmt 1 view -0
.cfi_startproc
.LBB99:
.LBI99:
.loc 2 35 1 view .LVU4
.loc 2 35 1 is_stmt 0 view .LVU5
.LBE99:
.cfi_endproc
.LFE3844:
.size _ZN5boost6detail7variant15visitation_implIN4mpl_4int_ILi20EEENS1_20visitation_impl_stepINS_3mpl6l_iterINS7_5l_endEEESA_EENS1_14invoke_visitorINS1_15result_wrapper1IZ4testRKNS_7variantINS1_14recursive_flagI5Obj_1EEJ5Obj_2EEEEUlRKT_E_SL_EELb0EEEPKvNSJ_18has_fallback_type_EEENT1_11result_typeEiiRSV_T2_NS3_5bool_ILb1EEET3_PSM_PT0_, .-_ZN5boost6detail7variant15visitation_implIN4mpl_4int_ILi20EEENS1_20visitation_impl_stepINS_3mpl6l_iterINS7_5l_endEEESA_EENS1_14invoke_visitorINS1_15result_wrapper1IZ4testRKNS_7variantINS1_14recursive_flagI5Obj_1EEJ5Obj_2EEEEUlRKT_E_SL_EELb0EEEPKvNSJ_18has_fallback_type_EEENT1_11result_typeEiiRSV_T2_NS3_5bool_ILb1EEET3_PSM_PT0_ |
Note clang can produce the same bad assembly by: So maybe it is not a GCC bug but rather a binutils one ... |
My bet is you might be able to reproduce the same issue with clang by adding:
To the end of lib.cpp |
You are right about the Clang behavior. So the problem can be addressed in any of the 4 places:
Linker discarding FDE doesn't fulfill the ELF spirit to me: input sections should be combined with no magical dropping rules. So perhaps assemblers are the right place to stop generating these FDE. |
The combination of exception handling, optimizations creating empty functions and using LLD exposes an upstream issue in the toolchain which leads to `libgcc` and `libunwind` crashing on malformed data: llvm/llvm-project#61434 The issue is most easily worked around by not using LLD in release builds. Other fixes such as reducing our use of `llvm_unreachable` or checking whether there are compiler options to avoid emitting zero-sized functions can be considered in the future. Until this issue is fixed upstream, change our CI to not use LLD in fully optimized builds and add code to cmake to warn when using release builds with LLD to avoid the issue.
The combination of exception handling, optimizations creating empty functions and using LLD exposes an upstream issue in the toolchain which leads to `libgcc` and `libunwind` crashing on malformed data: llvm/llvm-project#61434 The issue is most easily worked around by not using LLD in release builds. Other fixes such as reducing our use of `llvm_unreachable` or checking whether there are compiler options to avoid emitting zero-sized functions can be considered in the future. Until this issue is fixed upstream, change our CI to not use LLD in fully optimized builds and add code to cmake to warn when using release builds with LLD to avoid the issue.
The combination of exception handling, optimizations creating empty functions and using LLD exposes an upstream issue in the toolchain which leads to `libgcc` and `libunwind` crashing on malformed data: llvm/llvm-project#61434 This has also lead to our CI crashing: https://github.com/JLLVM/JLLVM/actions/runs/7346263904/job/20000726099 The issue is most easily worked around by not using LLD in release builds. Other fixes such as reducing our use of `llvm_unreachable` or checking whether there are compiler options to avoid emitting zero-sized functions can be considered in the future. Until this issue is fixed upstream, change our CI to not use LLD in fully optimized builds and add code to cmake to warn when using release builds with LLD to avoid the issue.
Consider the following simple example:
lib.cpp
lib.h
main.cpp
When building the code using
g++
and linking withlld
, the exception thrown by the call totest(Obj_1{"foo"});
is never caught, and the program terminates.Please note that the program executes successfully with the following configurations:
lib.cpp
The versions of the software used are the following:
bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)"
)A docker image with all the dependencies reproducing the issue is available in the example.
Please let me know if you need more information, or if the issue should be on the GCC side.
Best regards
The text was updated successfully, but these errors were encountered: