| Summary: | Patchelf can link against an incompatible libc++ version | ||
|---|---|---|---|
| Product: | buildroot | Reporter: | Bradley Gamble <bradley.gamble> |
| Component: | Other | Assignee: | unassigned |
| Status: | RESOLVED INVALID | ||
| Severity: | normal | CC: | buildroot |
| Priority: | P5 | ||
| Version: | 2019.05.1 | ||
| Target Milestone: | --- | ||
| Hardware: | PC | ||
| OS: | Linux | ||
| Host: | Target: | ||
| Build: | |||
I don't really see how this can happen, since Buildroot is building patchelf for the host before running it. The only reasons why it could fail like this is if: - The patchelf binary is built on one system, and move to another, which has an older libstdc++ library - The system on which you're doing the build has some kind of configuration/installation issue, and the C++ programs being built cannot be executed. All what Buildroot is doing is to build host-patchelf, which basically uses your system g++ compiler. Could you attach the broken patchelf binary ? Could you also attach the build log of the host-patchelf package ? The build is completed in a single container without any sort of file migration. My build commands are:
wget https://buildroot.org/downloads/buildroot-2019.05.1.tar.gz
tar -xvf ./buildroot-2019.05.1.tar.gz
cp ./baseimage/defconfig ./buildroot-2019.05.1/configs/custom_defconfig
make -C buildroot-2019.05.1 custom_defconfig
make -C buildroot-2019.05.1
This completes successfully, for example, on my host machine with newer libraries.
In the container I am able to build and C++ applications without issue - We compile many C++ binaries from source and this example of Patchelf is the only failure we've encountered. I have demonstrated this by building a hello world example:
$ cat helloworld.cpp
#include <iostream>
using namespace std;
int main()
{
cout << "Hello, World!";
return 0;
}
$ g++ helloworld.cpp -ohelloworld
$ ./helloworld
Hello, World!
I have uploaded the files here: https://gofile.io/?c=INwQ9u (Apologies for the third-party host, the binaries are too big to upload even when compressed.)
This tarball contains the Patchelf binary and log from Buildroot, as well as one I have manually compiled in the container. The Buildroot binary fails to execute from within the container, whereas the manually built one executes without issue.
Thank you for the files. I still believe the issue is in your Docker container itself. The symbol that triggers this is __throw_out_of_range_fmt: $ readelf -a patchelf-buildroot | grep 3\\.4\\.20 0000006203c0 000500000007 R_X86_64_JUMP_SLO 0000000000000000 _ZSt24__throw_out_of_r@GLIBCXX_3.4.20 + 0 It is linked only if you use a class which may throw an out of range error. However, it should get pulled in by <string> which (eventually) includes <bits/basic_string.h>. So the simple helloworld.cpp wouldn't trigger it, but if you do something like std::string("foo")[4] you should actually trigger this exception and hit that code path. In addition, for Buildroot builds you use /opt/gcc/4.9/bin/g++ while for the helloworld compilation you use just g++, which is probably /usr/bin/g++. I suspect that the problem is that /opt/gcc/4.9/bin/g++ does not set a proper RPATH for its libstdc++. You could add it to /etc/ld.so.conf, but I don't know if ld.so is smart enough to use a different version of a dynamic library depending of the symbols that are requested. You could also try to export HOST_LDFLAGS="-Wl,-rpath=/opt/gcc/4.9/lib" (or whatever the path is that contains GCC 9's libstdc++.so). In any case, I'm pretty sure this is due to a broken toolchain in your container and not due to a Buildroot issue, and definitely nothing that we can do about it. So I'm closing this as invalid. That said, don't hesitate to continue asking help either here or on the mailing list or on IRC. |
Attempting a build of buildroot can fail if the host machine is using an older version of libstdc++. In this instance I was using a Docker container with libstdc++ 3.4.13 (GLIBCXX_3.4.13). The truncated output from the build is as follows: >>> Sanitizing RPATH in target tree /home/bgamble/buildroot-2019.05.1/support/scripts/fix-rpath target Error: can't execute patchelf utility '/home/bgamble/buildroot-2019.05.1/output/host/bin/patchelf' make[1]: *** [target-finalize] Error 1 make: *** [_all] Error 2 Attempting to manually execute the patchelf binary will give the following error message: $ ./output/host/bin/patchelf ./output/host/bin/patchelf: /usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.20' not found (required by ./output/host/bin/patchelf) This means that it is not possible to perform a build with an older version of the libstdc++ library. It is possible to build and execute patchelf manually using the host compiler so I believe this is a Buildroot-specific issue and not caused by the upstream Patchelf source.