Problem with pthread_xxx code (version GLIBCXX_3.4.21 not found)
While playing with pthread_create() and pthread_join() in a C++ source code, I get this strange error :
robot@ev3dev:~/snir2$ ./test_threads
terminate called after throwing an instance of '__gnu_cxx::__concurrence_broadcast_error'
what(): __gnu_cxx::__concurrence_broadcast_error
Abandon
After googling it, I have read some solution from issue #27
I installed docker image and compiled the same source code with :
arm-linux-gnueabi-g++ -o test_threads -std=c++11 -static test_threads.cpp ev3dev.cpp -lpthread
I quess these error is strongly linked to the static compilation.
From the docker image, I compiled with :
arm-linux-gnueabi-g++ -o test_threads -std=c++11 test_threads.cpp ev3dev.cpp -lpthread
Now, I get an error dealing with the libstdc++ version :
./test_threads: /usr/lib/arm-linux-gnueabi/libstdc++.so.6: version GLIBCXX_3.4.21 not found (required by ./test_threads)
I have no clue how to fix all these errors...
ev3dev version installed on the robot is :
robot@ev3dev:~/snir2$ uname -a
Linux ev3dev 4.4.87-22-ev3dev-ev3 #1 PREEMPT Sat Sep 9 14:45:55 CDT 2017 armv5tejl GNU/Linux
Have you looked at #17, #28, #37? Usually, you get version GLIBCXX_x.x.x not found errors when different versions of the standard c++ library are used during compilation and at runtime.
I'd like to be able to tell you more, but I have not tried to compile and run anything on the brick for quite some time.
Like it is said in the stackoverflow discussion about static compilation (from issue #17), it works now when compiling from the docker image with the -static-libstdc++ option. As I understand, it compile statically only the libstdc++.
The final working compilation command is now :
arm-linux-gnueabi-g++ -o test_threads -std=c++11 -static-libstdc++ test_threads.cpp ev3dev.cpp -lpthread
Thank you very much @ddemidov for your help.
I have this exact same issue, but when I try to use -static-libstdc++ and -static-libgcc It gives me an error. /usr/bin/arm-linux-gnueabi-ld: cannot find -lstdc++: No such file or directory. This is on arch linux.
Build commands:
arm-linux-gnueabi-g++ -c ../src/test.cpp
arm-linux-gnueabi-g++ -o main test.o -static-libstdc++ -static-libgcc
Here is the test.cpp
#include "iostream"
int main(int argc, char *argv[]) {
std::cout << "Hello C++" << std::endl;
return 0;
}
Here is the full output in verbose mode: https://pastebin.com/9q66Nc76
Compiler was made by build and installing all these aur packages in order. Then changing the applicable ones from gnuabihf to gnuabi and removing all the last three arguments. I used the gnuabihf versions because the AUR packages for gnuabi are only binutils and gcc-stage1. Those arguments were to do with enabling the fpu. I also changed the versions of the linux headers to the kernel version of ev3dev (4.14.117) and I changed the version of glibc to the version reported by ldd (2.24).
https://aur.archlinux.org/packages/arm-linux-gnueabihf-binutils https://aur.archlinux.org/packages/arm-linux-gnueabihf-gcc-stage1 https://aur.archlinux.org/packages/arm-linux-gnueabihf-linux-api-headers https://aur.archlinux.org/packages/arm-linux-gnueabihf-glibc-headers https://aur.archlinux.org/packages/arm-linux-gnueabihf-gcc-stage2 https://aur.archlinux.org/packages/arm-linux-gnueabihf-glibc https://aur.archlinux.org/packages/arm-linux-gnueabihf-gcc
That took four hours and compiling gcc three separate times. Great fun.
That works for things that don't pull in libstdc++ or libgcc ie my hello world program. But when I go to use this library it pulls in both those and as the AUR packages were set up to use gcc 12 they are too new. When I compile normally it tries to dynamically link to them and can't find them on the brick.
So I came here and tried to use the gcc options and then it can't find libstd++ but it does seem to statically link libgcc. Short of compiling gcc 6 and getting the right libstdc++ how can I get it to statically link the gcc 12 libstdc++ right?
For some reason the https://aur.archlinux.org/packages/arm-linux-gnueabihf-gcc package was stripping the static libraries so adding staticlibs to options=(!emptydirs !distcc !strip) making it options=(!emptydirs !distcc !strip staticlibs) works to preserve them. This allowed -static-libstdc++ to work. I had set the libc version to the correct one when making my cross compiler and the ev3 version of libgcc worked so the dynamic versions worked for me, but there was one issue.
The produced binary with libstdc++.a was about 8 MB which took about 10 seconds to scp over usb to the brick. Without it the library was about 140 Kb. I wanted to cut down on the amount of copy time for it and I found that I could force the use of my own libstdc++.so.
This was done by setting the rpath (-Wl,-rpath=lib for gcc) to a lib folder in the working directory, putting the newer cross-compiled libstdc++.so.6 in there (from /usr/arm-linux-gnueabi/lib/libstdc++.so.6.0.30 on my system with my libstdc++ version), and it would try to use that not the system one. If you set LD_DEBUG=libs then it will show the library searching if it's looking for a libstdc++.so by a different name. On my ev3 it looked for libstdc++.so.6