Bug 1999657

Summary: Segfault when -flto is used to compile Catch framework tests on RHEL 8.4
Product: Red Hat Enterprise Linux 8 Reporter: Jiri Danek <jdanek>
Component: binutilsAssignee: Nick Clifton <nickc>
binutils sub component: system-version QA Contact: qe-baseos-tools-bugs
Status: CLOSED CURRENTRELEASE Docs Contact:
Severity: unspecified    
Priority: unspecified CC: ahajkova, fweimer, jakub, mpolacek, mprchlik, ohudlick
Version: 8.4Keywords: Bugfix, Triaged
Target Milestone: rc   
Target Release: ---   
Hardware: Unspecified   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: No Doc Update
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2021-09-03 10:32:12 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Attachments:
Description Flags
test_main.cpp none

Description Jiri Danek 2021-08-31 13:59:39 UTC
Created attachment 1819417 [details]
test_main.cpp

Created attachment 1819417 [details]
test_main.cpp

Description of problem:

Unit tests in a layered product fail with SIGSEGV when product is compiled with Link Time Optimization.


Version-Release number of selected component (if applicable):

The crash when using LTO happens on RHEL 8.4. On RHEL 8.3, with older GCC version, this works fine.

We also tested on the current ubi8 docker image, where the segfault also happens.

How reproducible:

Always.


Steps to Reproduce:

0. Download the .hpp and .c files from attachments.

1. Compile the attached reproducer with LTO:

    g++ -I . test_main.cpp -flto -fno-fat-lto-objects -o test

2. Run the result

    ./test

3. Observe the crash

$ gdb -quiet -ex 'set pagination off' -ex run -ex 'thread apply all bt' -ex 'set confirm off' -ex quit --args ./test
Reading symbols from ./test...(no debugging symbols found)...done.
Starting program: /mnt/repos/docker_repos/qpid-proton/reproducer/test 

Program received signal SIGSEGV, Segmentation fault.
0x0000000000000000 in ?? ()

Thread 1 (process 4926):
#0  0x0000000000000000 in ?? ()
#1  0x000000000040e30b in std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::shared_ptr<Catch::IReporterFactory> >::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::shared_ptr<Catch::IReporterFactory>, true>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::shared_ptr<Catch::IReporterFactory> const&) [clone .lto_priv.1324] ()
#2  0x0000000000485de5 in void __gnu_cxx::new_allocator<std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::shared_ptr<Catch::IReporterFactory> > > >::construct<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::shared_ptr<Catch::IReporterFactory> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::shared_ptr<Catch::IReporterFactory> const&>(std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::shared_ptr<Catch::IReporterFactory> >*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::shared_ptr<Catch::IReporterFactory> const&) ()
#3  0x000000000047f974 in void std::allocator_traits<std::allocator<std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::shared_ptr<Catch::IReporterFactory> > > > >::construct<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::shared_ptr<Catch::IReporterFactory> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::shared_ptr<Catch::IReporterFactory> const&>(std::allocator<std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::shared_ptr<Catch::IReporterFactory> > > >&, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::shared_ptr<Catch::IReporterFactory> >*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::shared_ptr<Catch::IReporterFactory> const&) ()
#4  0x0000000000477400 in void std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::shared_ptr<Catch::IReporterFactory> >, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::shared_ptr<Catch::IReporterFactory> > >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::shared_ptr<Catch::IReporterFactory> > > >::_M_construct_node<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::shared_ptr<Catch::IReporterFactory> const&>(std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::shared_ptr<Catch::IReporterFactory> > >*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::shared_ptr<Catch::IReporterFactory> const&) ()
#5  0x000000000046a55c in std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::shared_ptr<Catch::IReporterFactory> > >* std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::shared_ptr<Catch::IReporterFactory> >, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::shared_ptr<Catch::IReporterFactory> > >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::shared_ptr<Catch::IReporterFactory> > > >::_M_create_node<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::shared_ptr<Catch::IReporterFactory> const&>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::shared_ptr<Catch::IReporterFactory> const&) ()
#6  0x000000000045bc2e in std::pair<std::_Rb_tree_iterator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::shared_ptr<Catch::IReporterFactory> > >, bool> std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::shared_ptr<Catch::IReporterFactory> >, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::shared_ptr<Catch::IReporterFactory> > >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::shared_ptr<Catch::IReporterFactory> > > >::_M_emplace_unique<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::shared_ptr<Catch::IReporterFactory> const&>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::shared_ptr<Catch::IReporterFactory> const&) ()
#7  0x000000000044cc3a in std::pair<std::_Rb_tree_iterator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::shared_ptr<Catch::IReporterFactory> > >, bool> std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::shared_ptr<Catch::IReporterFactory>, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::shared_ptr<Catch::IReporterFactory> > > >::emplace<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::shared_ptr<Catch::IReporterFactory> const&>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::shared_ptr<Catch::IReporterFactory> const&) ()
#8  0x000000000042c181 in Catch::ReporterRegistry::registerReporter(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::shared_ptr<Catch::IReporterFactory> const&) ()
#9  0x000000000042be13 in Catch::(anonymous namespace)::RegistryHub::registerReporter(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::shared_ptr<Catch::IReporterFactory> const&) ()
#10 0x0000000000452583 in Catch::ReporterRegistrar<Catch::CompactReporter>::ReporterRegistrar(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) ()
#11 0x00000000004ae407 in __static_initialization_and_destruction_0(int, int) ()
#12 0x00000000004b6d2a in _GLOBAL__sub_I__ZN5Catch6Detail6ApproxC2Ed ()
#13 0x00000000004b6d7d in __libc_csu_init ()
#14 0x00007ffff70ff41e in __libc_start_main (main=0x447031 <main>, argc=1, argv=0x7fffffffec98, init=0x4b6d30 <__libc_csu_init>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffec88) at ../csu/libc-start.c:270
#15 0x000000000040724e in _start ()

Actual results:

SIGSEGV

Expected results:

===============================================================================
No tests ran

(there are no tests defined in the reproducer program, the segfault happens during testrunner initialization)

Additional info:

https://issues.redhat.com/browse/ENTMQCL-2669 Proton unittests fail on RHEL 8.4 when run the way QE runs them from srpm

Notes from Andrew Sticher from debugging the problem, Jira comment https://issues.redhat.com/browse/ENTMQCL-2781?focusedCommentId=16238266&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-16238266

Comment 2 Marek Polacek 2021-08-31 15:34:33 UTC
Reproduced with gcc-8.4.1-1.el8.x86_64.

Comment 3 Marek Polacek 2021-08-31 18:32:49 UTC
This is actually a regression between binutils-2.30-80.el8.x86_64 (OK) and binutils-2.30-82.el8.x86_64 (crash).

# g++ test_main.ii -flto -fno-fat-lto-objects -o test -fuse-ld=bfd; ./test
Segmentation fault (core dumped)
# g++ test_main.ii -flto -fno-fat-lto-objects -o test -fuse-ld=gold; ./test
===============================================================================
No tests ran

Comment 4 Marek Polacek 2021-08-31 18:41:42 UTC
I think I'll go ahead and try backporting https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=041d1c2d4f03a134cb7574e4d62d2ce4418503ff to binutils -- I think that may fix this problem.

Comment 5 Marek Polacek 2021-08-31 18:51:35 UTC
This actually already works with the latest binutils, I think it was fixed in

* Thu Mar 18 2021 Nick Clifton  <nickc> - 2.30-94
- Fix LTO and weak symbols again.  (#1930988)

Comment 6 Nick Clifton 2021-09-01 09:28:08 UTC
(In reply to Marek Polacek from comment #5)
> This actually already works with the latest binutils, I think it was fixed in
> 
> * Thu Mar 18 2021 Nick Clifton  <nickc> - 2.30-94
> - Fix LTO and weak symbols again.  (#1930988)

Thanks for tracking this down Marek.

OK, so the patch for 2.30-94 went into RHEL-8.5 binutils, but it did not make it into RHEL-8.4 binutils.

Jiri - is this problem important enough to warrant a z-stream update for RHEL-8.4 ?

Comment 7 Jiri Danek 2021-09-02 15:21:53 UTC
We disabled LTO in our latest published release, to workaround the bug. IMO we are good waiting for 8.5 to go out, and then removing the workaround.

If nobody else is hitting this linking problem, then I think it does not make sense to release a fix for RHEL 8.4.

(I tried to update the ticket with the above by replying to change notification e-mail. Evidently it did not get added as comment.)

Comment 8 Nick Clifton 2021-09-03 10:32:12 UTC
Ok then, I will CLOSE this BZ.