Linux starting an executable

How to run binary file in Linux

I have a file called commanKT and want to run it in a Linux terminal. Can someone help by giving the command to run this file? I tried ./commonRT but I’m getting the error:

"bash: ./commonrt: cannot execute binary file" [blackberry@BuildMc MainApp]$ ls -al commonKT -rwxrwxr-x. 1 sijith sijith 10314053 Feb 27 16:49 commonKT 

Assuming the problem isn’t just a mixup over names ( commonrt vs commonKT ), what does the command file commonKT /bin/sh say? If it gives two different architectures (perhaps one for ARM and one for Intel), then that’s why you can’t run the ARM one on an Intel machine.

In addition of using file , I also suggest using ldd ; perhaps the dynamic linker or some core shared library is different or missing.

Why does this question have so many upvotes? It contains so many variants of the questioned filename (commonrt, commonKT, commanKT, commonRT), that it’s not even clear what was asked. Also interesting: Does the last comment of Sijith mean that it is answered? And why did user1978011 receive bountys?

13 Answers 13

To execute a binary, use: ./binary_name .

bash: ./binary_name: cannot execute binary file

it’ll be because it was compiled using a tool chain that was for a different target to that which you’re attempting to run the binary on.

For example, if you compile ‘binary_name.c’ with arm-none-linux-gnueabi-gcc and try run the generated binary on an x86 machine, you will get the aforementioned error.

To execute a binary or .run file in Linux from the shell, use the dot forward slash friend

and if it fails say because of permissions, you could try this before executing it

 chmod +x binary_file_name # then execute it ./binary_file_name 

The volume it’s on is mounted noexec .

🙂 If not typo, why are you using ./commonRT instead of ./commonKT ??

It is possible that you compiled your binary with incompatible architecture settings on your build host vs. your execution host. Can you please have a look at the enabled target settings via

on your build host? In particular, the COLLECT_GCC_OPTIONS variable may give you valuable debug info. Then have a look at the CPU capabilities on your execution host via

cat /proc/cpuinfo | grep -m1 flags 

Look out for mismatches such as -msse4.2 [enabled] on your build host but a missing sse4_2 flag in the CPU capabilities.

If that doesn’t help, please provide the output of ldd commonKT on both build and execution host.

@craq I see that you gave me your bounty, thanks! Can you please give some info what the error was about?

This is an answer to @craq :

I just compiled the file from C source and set it to be executable with chmod. There were no warning or error messages from gcc.

I’m a bit surprised that you had to ‘set it to executable’ — my gcc always sets the executable flag itself. This suggests to me that gcc didn’t expect this to be the final executable file, or that it didn’t expect it to be executable on this system.

Читайте также:  Логотип операционной системы линукс

Now I’ve tried to just create the object file, like so:

$ gcc -c -o hello hello.c $ chmod +x hello 

( hello.c is a typical «Hello World» program.) But my error message is a bit different:

$ ./hello bash: ./hello: cannot execute binary file: Exec format error` 

On the other hand, this way, the output of the file command is identical to yours:

$ file hello hello: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped 

Whereas if I compile correctly, its output is much longer.

$ gcc -o hello hello.c $ file hello hello: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=131bb123a67dd3089d23d5aaaa65a79c4c6a0ef7, not stripped 

What I am saying is: I suspect it has something to do with the way you compile and link your code. Maybe you can shed some light on how you do that?

Источник

How to on starting processes (mostly in Linux)

Do you want to run an executable file from your program? Or execute a shell command programmatically? Or maybe just parallelize your code? Have you read a lot of information regarding execve() functions family and fork() but still have a mess in your head? Then this article is for you.

Join 5000 happy subscribers receiving my Cloud Native round-up and get deep technical write-ups from this blog direct into your inbox.

How to start Linux process

System calls

Let’s keep it simple and start from the beginning. We are developing a program for Linux. Let’s have a look on so called system calls — the interface Linux provides us to request kernel functionalities.

Linux has the next system calls to work with processes:

  • fork(void) ( man 2 fork ) — creates a full copy of the calling process. Sounds ineffecient because of need of copying the enterie process’s address space, but uses copy-on-write optimization. This is the only (ideological) way to create a process in Linux. However, in fresh versions of the kernel fork() is implemented on top of tricky clone() system call and now it’s possible to use clone() directly to create processes, but for simplicity we are going to skip these details.
  • execve(path, args, env) ( man 2 execve ) — transforms the calling process into a new process by executing a file under the specified path . In effect, it replaces the current process image with a new process image and doesn’t create any new processes.
  • pipe(fildes[2] __OUT) ( man 2 pipe ) — creates a pipe which is an inter-process communication primitive. Usually pipes are unidirectional data flows. The first element of the array connects to the read end of the pipe, and the second element connects to the write end. The data written to fildes[1] can be read from the fildes[0] .

We are not going to have a look at the aforementioned system calls source code because it’s a part of the kernel and could be hardly understandable.

Also an important part of our consideration is the Linux shell — a command interpreter utility (i.e. regular program). The shell process constantly reads from the stdin. A user usually interacts with the shell by typing some commands and pressing enter key. The shell process then executes provided commands. Standard outputs of these processes are connected to the stdout of the shell process. However, the shell process can be launched as a subprocess by itself and the command to execute can be specified via -c argument. Eg. bash -c «date» .

Читайте также:  Darkest dungeon для linux

C standard library

Of course we are developing our program in C to be as close to the OS-level primitives as possible. C has a so called standard library libc — a broad set of functions to simplify writing programs in this language. Also it provides wrapping around syscalls.

C standard library has the next functions (on Debian-based distros apt-get download glibc-source ):

  • system(command) ( man 3 system ) — launches a shell process to execute provided command . The calling process is blocked till the end of the execution of the underlying shell process. system() returns an exit code of the shell process. Let’s have a look on the implementation of this function in the stdlib:
int system(char *command) < // . skip signals tricks for simplicity . switch(pid = vfork()) < case -1: // error // . case 0: // child execl("/bin/sh", "sh", "-c", command, (char *)NULL); _exit(127); // will be called only if execl() returns, i.e. a syscall faield. >// . skip signals tricks for simplicity . waitpid(pid, (int *)&pstat, 0); // waiting for the child process, i.e. shell. return pstat.w_status; > 

So in effect, system() just uses the combination of the fork() + exec() + waitpid() .

  • popen(command, mode = ‘r|w’) ( man 3 popen ) — forks and replaces the forked process with a shell instance executing provided command. Sounds pretty the same like the system() ? The difference is an abilitiy to communicate with the child process via its stdin or stdout. But usually in the unidirectional way. To communicate with this process a pipe is used. Real implementations can be found here and here but the main idea is the following:
FILE * popen(char *program, char *type) < int pdes[2], fds, pid; pipe(pdes); // create a pipe switch (pid = vfork()) < // fork the current process case -1: // error // . case 0: // child if (*type == 'r') < dup2(pdes[1], fileno(stdout)); // bind stdout of the child process to the writing end of the pipe close(pdes[1]); close(pdes[0]); // close reading end of the pipe on the child side >else < dup2(pdes[0], fileno(stdin)); // bind stdin of the child process to the reading end of the pipe close(pdes[0]); close(pdes[1]); // close writing end of the pipe on the child side >execl("/bin/sh", "sh", "-c", program, NULL); // replace the child process with the shell running our command _exit(127); // will be called only if execl() returns, i.e. a syscall faield. > // parent if (*type == 'r') < result = pdes[0]; close(pdes[1]); >else < result = pdes[1]; close(pdes[0]); >return result; > 

Sidenote 1 — The shell‘s implementation of the subprocess launching is pretty the same. i.e. fork() + execve() .

Sidenote 2 — It’s good to mention that other programming languages usually implement bindings to the OS’s libc (and do some wrappings for convenience) to provide OS-specific funtionality.

Why to start Linux process

Parallelize execution

The simplest one. We need only fork() . Call of the fork() in effect duplicates your program process. But since this process uses completely separate address space to communicate with it we anyway need inter-process communication primitives. Even the instructions set of the forked process is the same as the parent’s one, it’s a different instance of the program.

Читайте также:  Huge pages linux oracle

Just run a program from your code

If you need just to run a program, without communicating with its stdin/stdout the libc system() function is the simplest solution. Yep, you also can fork() your process and then run exec() in the child process, but since it’s a quite common scenario there is system() function.

Run a process and read its stdout (or write to its stdin)

We need popen() libc function. Yep, you still can achieve the goal just by combining pipe() + fork() + exec() as shown above, but popen() is here to reduce the amount of boilerplate code.

Run a process, write to its stdin and read from its stdout

The most interesting one. For some reasons default popen() implementation is usually unidirectional. But looks like we can easily come up with the bidirectional solution: we need two pipes, first will be attached to child’s stdin and the second one to the child’s stdout. The remaining part is to fork() a child process, connect pipes via dup2() to IO descriptors and execve() the command. One of the potential implementations can be found on my GitHub popen2() project. An extra thing you should be aware while developing such function is leaking of open file descriptors of pipes from previously opened via popen() processes. If we forget to close explicitly foreign file descriptors in each child fork, there will be a possibility to do IO operations with the siblings’ stdin s and stdout s. Sounds like a vulnerability. To be able to close all those file descriptors we have to track them. I used a static variable with the linked list of such descriptors:

static files_chain_t *files_chain; file_t *popen2(const char *command) < file_t *fp = malloc(); // allocate new element of the chain _do_popen(fp, command); // add the current result to the chain fp->next = files_chain; files_chain = fp; > _do_popen() < // open pipes // fork() // if is_child: // for (fp in files_chain): // close(fp->in); close(fp->out); > int pclose2(file_t *fp) < // if (fp in files_chain): // . do payload . // remove fp from the chain free(fp); // DO NOT FORGET TO FREE THE MEMORY WE ALLOCATED DURING popen2() CALL >

A few words about Windows

Windows OS family have a slightly different paradigm for working with processes. If we skip neoteric Unix compatibility layer introduced on Windows 10 and attempts to port POSIX API support for Windows we will have only two functions from the oldschool WinAPI:

  • CreateProcess(filename) — starts a brand new process for a given executable.
  • ShellExecute(Ex)(command) — starts a shell (yep, Windows also has a shell concept) process to execute provided command.

So, no fork s and execve s. However, to communicate with the started processes pipes also can be used.

Instead of conclusions

Written by Ivan Velichko

Follow me on twitter @iximiuz

Join 5000 happy subscribers receiving my Cloud Native round-up and get deep technical write-ups from this blog direct into your inbox.

Источник

Оцените статью
Adblock
detector