Article Directory
1 write in front
In a technical exchange group, a small partner raised an unusual problem and transplanted an open source software to his own Ubuntu. When it was executed, it prompts "there is no such file". Check through "ls -l", the file does exist; This little partner has also been modified to rule out permission issues. Good guy, I'm depressed right now. The execution of the suggestions I gave is to “file file-name”
view the file information, and the implementation to “uname -a”
view the current system information, to check whether the executable file and the system version match. Sure enough, the executable file is in X86 format (32-bit system), and the system is X64, which will inevitably lead to execution failure. But this tip is misleading. It turns out that this executable file is also transplanted from the source code folder, and may be a file compiled by the author. Later, the small partners solved the problem in the form of patches. Now that the source code is available, it is possible to recompile the executable file on your own machine.
2 Case analysis
Write a basic program test.c
, compile the executable files of different systems and different architectures, and execute them.
#include <stdio.h>
int main(int argc, char *argv[])
{
printf("Hello acuity\r\n");
return 0;
}
Operating systems with different bits
Compile and execute on 64-bit Ubuntu16 and 32-bit Ubuntu10 respectively.
- The file compiled by 64-bit Ubuntu16 is
test0
- The file compiled by 32-bit Ubuntu10 is
test1
The two programs were executed on two systems, test0
and test1
both can be executed successfully on Ubuntu16 -64; test0
execution failed on Ubuntu10 -32.
Through the results of the two executions, it is inevitable that 64-bit systems are compatible with 32-bit system programs for X86 and X64 CPUs, or most of them are compatible. However, 32-bit systems cannot be compatible with 64-bit programs, which is understandable. Big is compatible with small, and small is not compatible with big anyway. However, a 64-bit system is not necessarily fully compatible with 32-bit applications. The phenomenon mentioned in the article is an example of incompatibility, which may be related to the gcc compiler version. Therefore, it is recommended to recompile and execute the same code under different systems. file.
CPUs of different architectures
Use a cross compiler to “aarch64-linux-gnu-gcc”
compile an executable file of the ARM architecture cpu test2
.
Executed on an X64 cpu machine, there is no doubt that the execution fails. There is no relevant dynamic library, even if there is relevant dynamics, it is impossible to execute. Conversely, X86 and X64 cpu executable programs cannot be executed successfully under ARM architecture cpu. This is also the problem that some people encounter clearly that the file is already on the board but cannot be executed.
For similar problems, sum up the following similar debugging and troubleshooting techniques, and get twice the result with half the effort.
3 Extension of debugging skills
3.1 View system information
command:uname -a
System information can be used to determine whether the driver and application software match the system. For example, if the kernel used for compiling a driver does not match the current system kernel, the driver will fail to load.
acuity@ubuntu:/mnt/hgfs/LSW/test$ uname -a
Linux ubuntu 4.15.0-101-generic #102~16.04.1-Ubuntu SMP Mon May 11 11:38:16 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
3.2 View file information
command:file file-name
For the execution file, the file information is used to determine whether it matches the current execution system environment, refer to the example described above.
View the execution file teset0 information:
acuity@ubuntu:/mnt/hgfs/LSW/test$ file test0
test0: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=8c9c6802aff5fc032c8cf947f7f09124ed03872c, not stripped
- Format: ELF64
- Small endian: little endian
- System environment: 64-bit (X86-64)
View non-executable file information:
acuity@ubuntu:/mnt/hgfs/LSW/test$ file test.c
test.c: C source, ASCII text, with CRLF line terminators
3.3 View file header
command:readelf -h file-name
View the file header information, you can more intuitively see the file type, system type, dependency information, etc., and the readability is more friendly. It is convenient to compare whether the file matches the execution system environment.
acuity@ubuntu:/mnt/hgfs/LSW/test$ readelf -h test0
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x400430
Start of program headers: 64 (bytes into file)
Start of section headers: 6616 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 56 (bytes)
Number of program headers: 9
Size of section headers: 64 (bytes)
Number of section headers: 31
Section header string table index: 28
Of course, for non-executable files, there is no file header information, and this command will return failure.
acuity@ubuntu:/mnt/hgfs/LSW/test$ readelf -h test.c
readelf: Error: Not an ELF file - it has the wrong magic bytes at the start
3.4 View the space occupied by files
command:size file-name
When using IED to develop MCU programs, you can view the occupancy of each segment of the compiled file. Similarly, it is also possible under linux, just execute a command. According to the information of each paragraph, the code can be optimized.
acuity@ubuntu:/mnt/hgfs/LSW/test$ size test0
text data bss dec hex filename
1200 552 8 1760 6e0 test0
- text, code segment, code and constant area
- data, data segment, store initialized global variables, global or local static variables
- bss, bss segment, stores uninitialized global variables (usually filled with 0)
- Decimal format of the sum of dec, decimal, text, data, and bss
- hex, hexadecimal, hexadecimal format of the sum of text, data, bss
3.5 View file execution permissions
command:ls -l file-name
When a program fails to execute, the most common cause of failure is permission problems, no execution attributes or insufficient execution user rights.
acuity@ubuntu:/mnt/hgfs/LSW/test$ ls -l test0
-rwxrwxrwx 1 root root 8600 5月 30 10:51 test0
Note:
Modify file permissions command:,chmod mode file-name
such as chmod 777 test0
3.6 Dynamic library required to view files
command:ldd file-name
When executing the program, there are many cases of madness that lack of library files. At this time, we can first check which library files the executable file depends on through commands, and solve all library problems in one step.
acuity@ubuntu:/mnt/hgfs/LSW/test$ ldd test0
linux-vdso.so.1 => (0x00007fff46285000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f804405e000)
/lib64/ld-linux-x86-64.so.2 (0x00007f8044428000)
Check the executable file test2 under the ARM cpu in the previous example, it is not the executable file of the current machine.
acuity@ubuntu:/mnt/hgfs/LSW/test$ ldd test2
not a dynamic executable
3.7 Document verification
After file transfer or copying, if you are not sure whether the file is damaged or accidentally modified, you can check with the check value. Commonly used checks are sum check (sum), CRC check (cksum), md5sum. By comparing their check values, you can quickly check whether the file has been tampered with.
- sum,
sum [-r/-s] file-name
The [-r] option means to use the system v algorithm, using 1k bytes; when the default value is selected, the system v algorithm is used by default
[-s] option, means to use BSD algorithm, use 512 bytes
sum test0
32142 9
- CRC,
cksum file-name
acuity@ubuntu:/mnt/hgfs/LSW/test$ cksum test0
525748358 8600 test0
- md5sum;
md5sum file-name
acuity@ubuntu:/mnt/hgfs/LSW/test$ md5sum test0
cb245018f7f9e0a3d938ec363495e9be test0
3.8 View file symbol table
command: nm file-name |grep [fun/variable]
If you have obsessive-compulsive disorder, you can use this command to check whether a function or variable is compiled in, and their execution address. Check the main function in the test0 execution file.
acuity@ubuntu:/mnt/hgfs/LSW/test$ nm test0|grep main
U __libc_start_main@@GLIBC_2.2.5
0000000000400526 T main
3.9 View string in file
command: strings file-name|grep string-name
Through this command, you can check whether the constant characters are compiled into the target file. The most practical is to check the file version information (character type). Of course, you can also use a binary viewing tool (such as UE) to open the executable file and directly search for the target character file.
Check the "Hello" character in the test0 file:
acuity@ubuntu:/mnt/hgfs/LSW/test$ strings test0|grep Hello
Hello acuity
Search for characters with binary file reading tool:
3.10 File space optimization
Command: strip file-name
This command can optimize and delete some symbol information and debugging information (gdb) of the executable file to save space; but after optimization, the program will be abnormal, and it will not be able to record and generate some reference information. Generally, optimization and reduction of space will be made when the software is released.
The space before and after optimization of test0 file:
acuity@ubuntu:/mnt/hgfs/LSW/test$ ls -l test0
-rwxrwxrwx 1 root root 8600 5月 31 00:09 test0
acuity@ubuntu:/mnt/hgfs/LSW/test$ strip test0
acuity@ubuntu:/mnt/hgfs/LSW/test$ ls -l test0
-rwxrwxrwx 1 root root 6320 5月 31 00:09 test0