Bug 2101570
| Summary: | gcc on RHEL7 does not produce usable binaries using target and target_clone syntax | ||||||
|---|---|---|---|---|---|---|---|
| Product: | Red Hat Developer Toolset | Reporter: | Andrew Mike <amike> | ||||
| Component: | gcc | Assignee: | Marek Polacek <mpolacek> | ||||
| gcc sub component: | gcc-toolset-12 | QA Contact: | Václav Kadlčík <vkadlcik> | ||||
| Status: | CLOSED WONTFIX | Docs Contact: | |||||
| Severity: | medium | ||||||
| Priority: | medium | CC: | alanm, brclark, casantos, fweimer, jwright, mkielian, mkolbas, pandrade, philip.miloslavsky, vkadlcik | ||||
| Version: | DTS 11.1 RHEL 7 | ||||||
| Target Milestone: | alpha | ||||||
| Target Release: | 9.1 | ||||||
| Hardware: | x86_64 | ||||||
| OS: | Linux | ||||||
| Whiteboard: | |||||||
| Fixed In Version: | Doc Type: | If docs needed, set a value | |||||
| Doc Text: | Story Points: | --- | |||||
| Clone Of: | Environment: | ||||||
| Last Closed: | 2022-07-18 14:21:42 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: |
|
||||||
I don't think this is about what code gcc generates: the same code is emitted with GCC 11
on both RHEL 7 and 8. In fact, the binary built on RHEL8 crashes on RHEL7, and the binary
built on RHEL7 works on RHEL8.
# LD_LIBRARY_PATH=. gdb -q --args /lib64/ld-linux-x86-64.so.2 ./test_dlopen
Reading symbols from /lib64/ld-linux-x86-64.so.2...
Reading symbols from /usr/lib/debug/usr/lib64/ld-2.17.so.debug...
(gdb) r
Starting program: /usr/lib64/ld-linux-x86-64.so.2 ./test_dlopen
Opening libirisdb.so
Program received signal SIGSEGV, Segmentation fault.
0x00000000000010a6 in ?? ()
(gdb) bt
#0 0x00000000000010a6 in ?? ()
#1 0x00007ffff7ff4364 in ?? ()
#2 0x00007fffffffd920 in ?? ()
#3 0x00007ffff7de76c8 in elf_machine_rela (reloc=0x7ffff7ff38f8, reloc=0x7ffff7ff38f8,
skip_ifunc=<optimized out>, reloc_addr_arg=0x7ffff7ff7038, version=<optimized out>, sym=0x7ffff7ff34d8,
map=0x7ffff7fff030) at ../sysdeps/x86_64/dl-machine.h:308
#4 elf_dynamic_do_Rela (skip_ifunc=<optimized out>, lazy=<optimized out>, nrelative=<optimized out>,
relsize=<optimized out>, reladdr=<optimized out>, map=0x7ffff7fff030) at do-rel.h:137
#5 _dl_relocate_object (scope=<optimized out>, reloc_mode=<optimized out>,
consider_profiling=<optimized out>) at dl-reloc.c:259
Backtrace stopped: frame did not save the PC
tail of LD_DEBUG=all output just before the crash:
33847: symbol=_ZNSt8ios_base4InitC1Ev; lookup in file=/lib64/ld-linux-x86-64.so.2 [0]
33847: symbol=_ZNSt8ios_base4InitC1Ev; lookup in file=./libirisdb.so [0]
33847: symbol=_ZNSt8ios_base4InitC1Ev; lookup in file=/lib64/libstdc++.so.6 [0]
33847: binding file ./libirisdb.so [0] to /lib64/libstdc++.so.6 [0]: normal symbol `_ZNSt8ios_base4InitC1Ev' [GLIBCXX_3.4]
33847: symbol=_Z18optimized_functionIiiEiT_T0_; lookup in file=./test_dlopen [0]
33847: symbol=_Z18optimized_functionIiiEiT_T0_; lookup in file=/lib64/libdl.so.2 [0]
33847: symbol=_Z18optimized_functionIiiEiT_T0_; lookup in file=/lib64/libc.so.6 [0]
33847: symbol=_Z18optimized_functionIiiEiT_T0_; lookup in file=/lib64/ld-linux-x86-64.so.2 [0]
33847: symbol=_Z18optimized_functionIiiEiT_T0_; lookup in file=./libirisdb.so [0]
33847: binding file ./libirisdb.so [0] to ./libirisdb.so [0]: normal symbol `_Z18optimized_functionIiiEiT_T0_'
Reduced. If I remove the target_clones, it works.
# gcc test_dlopen.c -o test_dlopen -ldl; g++ -fpic -c l.cc; g++ -shared -o libirisdb.so l.o; LD_LIBRARY_PATH=. ./test_dlopen
Opening libirisdb.so
Segmentation fault
# cat test_dlopen.c
#include <stdio.h>
#include <dlfcn.h>
#define LIBRARY_NAME "libirisdb.so"
int main() {
// open the library
printf("Opening %s\n",LIBRARY_NAME);
void* handle = dlopen(LIBRARY_NAME, RTLD_NOW);
if (!handle) {
printf("open failed %s\n",dlerror());
return 1;
}
// close the library
printf("closing \n");
dlclose(handle);
return(0);
}
# cat l.cc
template <typename vector_T, typename elem_T>
__attribute__((target_clones("avx2", "default")))
int optimized_function(vector_T, elem_T)
{
return 1;
}
int mv_cppfunction(int input)
{
return optimized_function<int,int>(input,input);
}
This is a libgcc problem. We are calling __cpu_indicator_init, an external function from libgcc.so, while processing an IFUNC in a dlopen, and that function needs a run-time relocation, but at this point the relocation hasn't been set up yet. This work on RHEL8 because the system gcc has this patch: https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=abd0cdc9c07c92d6cab15afc4fd38945d536751b However, backporting the patch to RHEL7 at this stage is not feasible. There are 2 workarounds: 1) Link with -lgcc while creating libirisdb.so. Then libgcc.a (specifically, cpuinfo.o) will get pulled in while linking therefore avoiding the need to resolve the function at runtime. 2) Don't use the target_clones attribute. Obviously, the specialized avx2 functions will not be used then. Special thanks to Florian W. who found the root issue and the patch. Closing as I don't plan to change neither DTS gcc nor system RHEL7 libgcc. |
Created attachment 1893034 [details] Test package for issue Description of problem: When using devtoolset-10 on RHEL 7, gcc does not produce usable binaries using target and target_clone syntax. Version-Release number of selected component (if applicable): devtoolset-11-11.1-2.el7 How reproducible: 100% Steps to Reproduce: 1. Unzip test zip file into directory. 2. Run "make". 3. Run "LD_LIBRARY_PATH=." ./test_dlopen Actual results: Program crashes with segmentation fault. Expected results: Program works. Additional info: - This also fails on devtoolset-9 and -10, but only on RHEL 7; RHEL 8 appears unaffected.