Skip to content
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

aarch64-linux-gnu-g++ version 7.5.0 crash with segmentation fault #197

Closed
sagi-ottopia opened this issue Mar 22, 2023 · 14 comments
Closed
Assignees
Labels
bug Something isn't working

Comments

@sagi-ottopia
Copy link

Environment

toml++ version and/or commit hash: 7eb2ffc v3.3.0

Compiler: aarch64-linux-gnu-g++ (Linaro GCC 7.5-2019.12) 7.5.0

C++ standard mode: c++17

Target arch: aarch64

Library configuration overrides:

Relevant compilation flags:

Describe the bug

While trying to build the examples with the following commands:
compiler crashed with segmentation fault

Steps to reproduce (or a small repro code sample)

$ cmake -B build.gcc7 -DBUILD_EXAMPLES=1 -DCMAKE_CXX_COMPILER=/opt/toolchains/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-g++
$ cmake --build build.gcc7 --verbose

Additional information

image

@sagi-ottopia sagi-ottopia added the bug Something isn't working label Mar 22, 2023
@marzer
Copy link
Owner

marzer commented Mar 22, 2023

Can you include the error logs as actual text, instead of an image?

@sagi-ottopia
Copy link
Author

sure

[ 75%] Building CXX object examples/CMakeFiles/toml_merger.dir/toml_merger.cpp.o
In file included from /tmp/tomlplusplus/include/toml++/toml.h:69:0,
                 from /tmp/tomlplusplus/examples/toml_merger.cpp:9:
/tmp/tomlplusplus/include/toml++/impl/parser.inl: In member function ‘bool toml::v3::impl::utf8_reader<T>::read_next_block()’:
/tmp/tomlplusplus/include/toml++/impl/parser.inl:264:50: warning: requested alignment 32 is larger than 16 [-Wattributes]
    TOML_OVERALIGNED char raw_bytes[block_capacity];
                                                  ^
/tmp/tomlplusplus/include/toml++/impl/parser.inl: In function ‘toml::v3::ex::parse_result toml::v3::impl::do_parse_file(std::string_view)’:
/tmp/tomlplusplus/include/toml++/impl/parser.inl:3785:58: warning: requested alignment 32 is larger than 16 [-Wattributes]
   TOML_OVERALIGNED char file_buffer[sizeof(void*) * 1024u];
                                                          ^
In file included from /tmp/tomlplusplus/include/toml++/toml.h:48:0,
                 from /tmp/tomlplusplus/examples/toml_merger.cpp:9:
/tmp/tomlplusplus/include/toml++/impl/table.h: In instantiation of ‘toml::v3::table::do_for_each(Func&&, Table&&)::<lambda(auto:4&&)> [with auto:4 = toml::v3::table&; Func = {anonymous}::merge_left(toml::v3::table&, toml::v3::table&&)::<lambda(const toml::v3::key&, auto:13&&)>; Table = toml::v3::table&]’:
/opt/toolchains/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/aarch64-linux-gnu/include/c++/7.5.0/type_traits:2428:26:   required by substitution of ‘template<class _Fn, class ... _Args> static std::__result_of_success<decltype (declval<_Fn>()((declval<_Args>)()...)), std::__invoke_other> std::__result_of_other_impl::_S_test(int) [with _Fn = toml::v3::table::do_for_each(Func&&, Table&&) [with Func = {anonymous}::merge_left(toml::v3::table&, toml::v3::table&&)::<lambda(const toml::v3::key&, auto:13&&)>; Table = toml::v3::table&]::<lambda(auto:4&&)>&&; _Args = {toml::v3::table&}]’
/opt/toolchains/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/aarch64-linux-gnu/include/c++/7.5.0/type_traits:2439:55:   required from ‘struct std::__result_of_impl<false, false, toml::v3::table::do_for_each(Func&&, Table&&) [with Func = {anonymous}::merge_left(toml::v3::table&, toml::v3::table&&)::<lambda(const toml::v3::key&, auto:13&&)>; Table = toml::v3::table&]::<lambda(auto:4&&)>&&, toml::v3::table&>’
/opt/toolchains/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/aarch64-linux-gnu/include/c++/7.5.0/type_traits:2444:12:   required from ‘struct std::__invoke_result<toml::v3::table::do_for_each(Func&&, Table&&) [with Func = {anonymous}::merge_left(toml::v3::table&, toml::v3::table&&)::<lambda(const toml::v3::key&, auto:13&&)>; Table = toml::v3::table&]::<lambda(auto:4&&)>&&, toml::v3::table&>’
/opt/toolchains/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/aarch64-linux-gnu/include/c++/7.5.0/type_traits:2845:12:   [ skipping 2 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ]
/tmp/tomlplusplus/include/toml++/impl/node.h:735:37:   required from ‘constexpr const bool toml::v3::node::can_visit<toml::v3::table::do_for_each(Func&&, Table&&) [with Func = {anonymous}::merge_left(toml::v3::table&, toml::v3::table&&)::<lambda(const toml::v3::key&, auto:13&&)>; Table = toml::v3::table&]::<lambda(auto:4&&)>&&, toml::v3::node&, toml::v3::table>’
/tmp/tomlplusplus/include/toml++/impl/node.h:765:49:   required from ‘constexpr const bool toml::v3::node::visit_is_nothrow_one<toml::v3::table::do_for_each(Func&&, Table&&) [with Func = {anonymous}::merge_left(toml::v3::table&, toml::v3::table&&)::<lambda(const toml::v3::key&, auto:13&&)>; Table = toml::v3::table&]::<lambda(auto:4&&)>&&, toml::v3::node&, toml::v3::table>’
/tmp/tomlplusplus/include/toml++/impl/node.h:768:44:   required from ‘constexpr const bool toml::v3::node::visit_is_nothrow<toml::v3::table::do_for_each(Func&&, Table&&) [with Func = {anonymous}::merge_left(toml::v3::table&, toml::v3::table&&)::<lambda(const toml::v3::key&, auto:13&&)>; Table = toml::v3::table&]::<lambda(auto:4&&)>&&, toml::v3::node&>’
/tmp/tomlplusplus/include/toml++/impl/node.h:920:51:   required from ‘decltype(auto) toml::v3::node::visit(Func&&) & [with Func = toml::v3::table::do_for_each(Func&&, Table&&) [with Func = {anonymous}::merge_left(toml::v3::table&, toml::v3::table&&)::<lambda(const toml::v3::key&, auto:13&&)>; Table = toml::v3::table&]::<lambda(auto:4&&)>]’
/tmp/tomlplusplus/include/toml++/impl/table.h:897:16:   required from ‘static void toml::v3::table::do_for_each(Func&&, Table&&) [with Func = {anonymous}::merge_left(toml::v3::table&, toml::v3::table&&)::<lambda(const toml::v3::key&, auto:13&&)>; Table = toml::v3::table&]’
/tmp/tomlplusplus/include/toml++/impl/table.h:1042:15:   required from ‘toml::v3::table& toml::v3::table::for_each(Func&&) & [with Func = {anonymous}::merge_left(toml::v3::table&, toml::v3::table&&)::<lambda(const toml::v3::key&, auto:13&&)>]’
/tmp/tomlplusplus/examples/toml_merger.cpp:78:5:   required from here
/tmp/tomlplusplus/include/toml++/impl/table.h:912:44: internal compiler error: Segmentation fault
           visitor)(static_cast<const key&>(kvp.first), static_cast<value_ref>(v)));
                                            ^~~
Please submit a full bug report,
with preprocessed source if appropriate.
See <https://gcc.gnu.org/bugs/> for instructions.
gmake[2]: *** [examples/CMakeFiles/toml_merger.dir/build.make:76: examples/CMakeFiles/toml_merger.dir/toml_merger.cpp.o] Error 1
gmake[1]: *** [CMakeFiles/Makefile2:354: examples/CMakeFiles/toml_merger.dir/all] Error 2
gmake: *** [Makefile:156: all] Error 2

@marzer
Copy link
Owner

marzer commented Mar 22, 2023

Ah yup, I've had trouble with other older versions of GCC with over-alignment in the past, looks like more of the same. Should be easy to address, thanks for the report :)

@sagi-ottopia
Copy link
Author

Thank you for the quick response, currently I can't upgrade the compiler version that I use on that platform so a fix will be very helpful

@marzer
Copy link
Owner

marzer commented Mar 24, 2023

@sagi-ottopia I've just realized that I mis-read the error log and this isn't actually to do with over-alignment at all, but the template machinery that makes table::for_each() work. It might just be an ICE with that particular instantiation in the toml_merger example, and not actually the library itself; can you tell me if the simple_parser example compiles OK?

@sagi-ottopia
Copy link
Author

Yes, simple_parser compiles OK.
but I started to compile the examples code because when I'm compiling my code which uses the library this particular compiler crashed as well.

@marzer
Copy link
Owner

marzer commented Mar 24, 2023

Ah, OK, I see. Well I'll try to come up with a workaround but it might ultimately be the case that GCC 7 is a bit too broken - the lowest I'm able to easily test with these days is GCC 8.

@damirbarr
Copy link

Hi @marzer
Is there anything new with this issue?

@marzer
Copy link
Owner

marzer commented Apr 3, 2023

@damirbarr are you also experiencing the same issue? If so, which specific version of GCC and target environment, the same one as @sagi-ottopia?

@damirbarr
Copy link

damirbarr commented Apr 3, 2023

@marzer yes, the same one. I applied the following patch and was able to work around this issue. Now I'm compiling both with gcc-7 and gcc-10.

tomlplusplus-fix.zip

All my unit tests pass and I'm able to compile everything.
The issue is that I'll need to create my own Conan package with this workaround

@marzer
Copy link
Owner

marzer commented Apr 3, 2023

I applied the following patch and was able to work around this issue.

Hmmn, interesting. A worrying factor - a bool (or bool-convertible) return result of false from the for_each() callback is supposed to stop the iteration; your workaround deletes the branches responsible for handling that and always returns true, which effectively changes the API. Are you able to do some less destructive alterations, to find which specific construct in do_for_each triggers the ICE? My guess is the using return_type = ...; part, but I can't test at the moment.

If I can't modify for_each to support the bool propagation and have it still work on GCC 7 I will have to end support for GCC 7, unfortunately.

All my unit tests pass and I'm able to compile everything.

Looks like I am missing tests to ensure for_each() iteration does what it's supposed to do when you return false :P

@marzer
Copy link
Owner

marzer commented Apr 3, 2023

@damirbarr In 2414d90 I have added some additional tests to check for the above

@sagi-ottopia
Copy link
Author

Ah, OK, I see. Well I'll try to come up with a workaround but it might ultimately be the case that GCC 7 is a bit too broken - the lowest I'm able to easily test with these days is GCC 8.

  1. I can assist with checking on a relevant compiler and a machine. I have a cloud machine installed with Ubuntu 18.04 ARM64
  2. You can download the compiler from https://releases.linaro.org/components/toolchain/binaries/latest-7/aarch64-linux-gnu/

Sagi.

@marzer marzer closed this as completed in d46cac7 Sep 5, 2023
@marzer
Copy link
Owner

marzer commented Sep 5, 2023

Alright folks, sorry it took me so long to get back to this. I wasn't able to come up a workaround that preserved the same API (returning false to early exit the loop) since I think GCC 7 is just overtly broken in this area, so instead I've added an error message and some #define escape hatches.

  • By default, using a for_each() on GCC 7 will trigger a static assert
  • #define TOML_RETURN_BOOL_FROM_FOR_EACH_BROKEN_ACKNOWLEDGED indicates "yep, that's fine, I don't need to be able to early-exit from for_each()" (essentially this enables @damirbarr's patch)
  • #define TOML_RETURN_BOOL_FROM_FOR_EACH_BROKEN 0 overrides the default and indicates "no, actually, my compiler works fine, I want the normal API" (YMMV - if this works for you, please let me know)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants