Docker Centos, Cannot Execute Binary File - c++

I have one C++ binary which is running smoothly on local centos. Recently, I started learning docker and trying to run my C++ application on centos docker.
Firstly, I pulled centos:latest from docker hub and installed my C++ application on it and it ran successfully, without any issue. Now i installed docker on raspberry-pi and pulled centos again and tried to ran the same application on it but it gave me error.
bash : cannot execute binary file
Usually, this error comes when we try to run application on different architecture then the one they are built on. I checked cat etc/centos-release on raspberry-pi and result is CentOS Linux release 7.6.1810 (AltArch),where as result on local centos is CentOS Linux release 7.6.1810 (Core)
uname -a on both devices is as follows
raspberry-pi, centos docker Linux c475f349e7c2 4.14.79-v7+ #1159 SMP Sun Nov 4 17:50:20 GMT 2018 armv7l armv7l armv7l GNU/Linux
centos, centos docker Linux a57f3fc2c1a6 4.15.0-46-generic #49-Ubuntu SMP Wed Feb 6 09:33:07 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
EDIT:
Also, file myapplication
TTCHAIN: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), dynamically linked, interpreter /lib64/l, for GNU/Linux 2.6.24, BuildID[sha1]=287b501c8206893f7819f215ee0033586212b143, with debug_info, not stripped
My question is how can i ran the same native application of centos, pulled from docker on raspberry-pi model 3.

Your application has been built for x86-64. Intel x86-64 binaries CAN NOT run on an ARM processor.
You have two paths to pursue:
If you don't have source code for the application, you will need an x86-64 emulator that will run on your Raspberry Pi. Considering the Pi's lesser capabilities and Intel's proclivity to sue anyone who creates an emulator for their processors, I doubt you'll find one that's publicly available.
If you have the source code for the application, you need to rebuild it as a Raspberry Pi executable. You seem to know that it was written in C++. GCC and other toolchains are available for the Raspberry Pi (most likely a "yum install gcc" on your Pi will grab the compiler and tools for you). Building the application should be extremely similar to building it for x86_64.
You could find a cross-compiler that would let you build for the Pi from your x86_64 box, but that can get complicated.

Could be that you are trying to run a 64-bit binary on a 32-bit processor, would need more information to know for sure though.
You can check by using the file command in the shell. You may have to re-compile on the original system with the -m32 flag to gcc.

Please do a "uname -a" on both devices and post the results.
Most likely the processor or library type doesn't match.
I presume (hope) you're not trying to run an x86-compiled app on a Pi. Although Docker is available for both processor types, Docker will not run x86 binaries on Pi or vice versa.
Actually, AltArch currently means one of the following architectures... ppc64, ppc64le, i386, armhfp (arm v7 32-bit), aarch64 (arm v8 64-bit). Core suggests the mainstream x86 and x86_64 builds of CentOS.
Yep, I bet that's what it is...you can't just transfer an x86 binary to a Raspbian and expect it to work. The application must be rebuilt for the platform.

Related

How to cross compile linux arm to x86

I'm using an m1 pro macbook pro.
Up until now, I used intel macbook.
My program is written in c/c++ and the target is ubuntu x86_64.
I tried running ubuntu x86 docker (qemu) and it's super slow - to the point it's unusable.
I have linux ubuntu (arm) installed using parallels and would like to compile for x86 target instead of arm.
How do I do it?
On Ubuntu, I would suggest an apt install gcc-x86-64-linux-gnu g++-x86-64-linux-gnu, and then invoking the installed compiler with the x86-64-linux-gnu prefix (for gcc, x86-64-linux-gnu-gcc) to create x86_64 binaries.
Do note that if you target x86_64 you won't be able to run the programs you build natively, but you should be able to package the binaries created for execution on an x86_64 machine.
Install docker-desktop on your mac and run this docker container with the command:
docker container run --platform=linux/amd64 -it -p 6080:6080 -e WIDTH=1920 -e HEIGHT=1080 yoas1/xubuntu-desktop:1.0
Don't forget to create volume to the code directory.
In your browser go to: http://localhost:6080/vnc.html to access the xubuntu desktop
Image on Dockerhub

Selecting cross compiler for Raspberry Pi

Looking for cross compiler that could help me build application for Raspberry Pi on my Ubuntu 20.04 machine. I found official tools on Github and I suppose that folder arm-bcm2708 contains cross compilers:
arm-bcm2708hardfp-linux-gnueabi
arm-bcm2708-linux-gnueabi
arm-linux-gnueabihf -> arm-rpi-4.9.3-linux-gnueabihf
arm-rpi-4.9.3-linux-gnueabihf
gcc-linaro-arm-linux-gnueabihf-raspbian
gcc-linaro-arm-linux-gnueabihf-raspbian-x64
I'm confused what directories names is trying to tell me? I know following words:
arm - processor type used on Pi
bcm2708 - processor model used on pi
gnueabi - cross-compiler for armel architecture (you can build binary for ARM on PC)
linaro - company that creates multimedia for ARM
4.9.3 - I suppose is GCC compiler version (why it is so old?)
Which of compilers I should use for my Pi3 and Pi4?
You can use one of the toolchains provided by ARM for your RPI3/4.
If you are running a 32 bit Linux on your RPI3/4, use one of the arm-none-linux-gnueabihf toolchains, if use are running a 64 bit Linux on your RPI3/4, use one of the aarch64-none-linux-gnu one.
Both 10.2 and 9.2 versions of the two toolchains are working fine on my own Ubuntu 20.04.1 LTS x86_64 system. Of course, you can cross-compile programs with the arm-none-linux-gnueabihf toolchain and run them on the 64 bit Linux running on your RPI3/4 as well.

crosscompile c++ binary for Amazon EC2

I tried to just compile on what appears to be similar (both Ubuntu 64bit) but the binary is not runnable by the Amazon instance of Ubuntu (which is 64 bit too, but don't know much more than that).
I've seen a thread suggesting spinning additional EC2 instance just to compile there, but it isn't a solution as I can't transfer sources outside, only a compiled binaries and dynamic libs.
Was thinking about making a virtual environment on my computer to spawn a clone of EC2 to compile there, but is it doable?
kernel info:
uname -a
4.4.0-93-generic #116-Ubuntu SMP Fri Aug 11 21:17:51 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
ip-xxx-xxx-xxx-xxx 4.4.0-1035-aws #44-Ubuntu SMP Tue Sep 12 17:27:47 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
it uses some amazon tailor made kernel it seems?
file info:
file ./testBinary
./testBinary: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), too many program (2304)
file -Pelf_phnum=3000 ./testBinary
./testBinary: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), corrupted program header size, corrupted section header size
You can't really 'clone' EC2 instance that you've created from some AMI. So since you don't have any details about why exactly your library wasn't working, I would suggest running Amazon Linux instead of Ubuntu.
You can run Amazon Linux in a Docker container on your machine and build your library there (https://hub.docker.com/_/amazonlinux/). That way the library should run without problems in any EC2 with Amazon Linux.
If you want to stick with Ubuntu, at the very least you should match Ubuntu versions (not just architecture) and probably kernel versions.

Arm toolchain and associated runtime

I am attempting to port an application to an arm processor and have run into a roadblock. I don't get to change the source code and it uses a feature that is not available in the arm runtime on the arm host. I get the message on the arm host:
/usr/lib/arm-linux-gnueabihf/libstdc++.so.6: version 'CXXABI_1.3.8' not found (required by MyDaemon);
I ran
strings libstdc++.so.6 | grep CXXABI and got the list with the last element as CXXABI_1.3.6.
Can I simply replace the toolchain/runtime on the arm machine or do I have to worry about other programs that link to it and will not run any longer?
g++ --version gives (Debian 4.6.3-14) 4.6.3
so maybe I can use a 4.9 toolchain and runtime?
The issue with that answer is that when the different libstdc++ is loaded it reports.
GLIBC_2.17 not found
The problem is that the environment on the machine where the application is compiled is different from the environment where the application is run and would like to know where to read to be able to solve this problem.

Compiling amd64 binary on i386 root with amd64 kernel (Debian)

I have a rather old Debian testing system that has all packages installed as i386. Usually I'm running a PAE kernel (linux-image-3.16.0-4-686-pae:i386).
I'm trying to compile a simple C++ program that needs more than 4 GB of memory. I've installed the linux-image-3.16.0-4-amd64:amd64 kernel because I think it is not possible to get more than 3GB of memory on a PAE machine.
Unfortunately, the whole toolchain/libraries are still i386. I guess I need a special flavour of GCC (multilib?) and the amd64 version of some libraries.
I've found tutorials on how to compile 32bit stuff on 64bit rootfs systems, but not the other way round. I don't want to cross-grade the whole system to amd64 just for this test, so:
Is there a way to safely compile and run 64bit code on this setup with as little changes to the system as necessary? Ideally it would be possible to cross-grade from this setup at some point in the future. Alternately, would it be possible to create a 64bit chroot environment from a Debian Live CD, chroot into it, compile the code and run it from there? Or compile it statically and run it outside the chroot?
EDIT: Installing g++multilib solves the problem compiling 64bit (using the -m64 option). Can anyone help with the chroot / cross-grade part of my question?