[Code debugging] Several practical Linux application debugging skills



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 istest0
  • The file compiled by 32-bit Ubuntu10 istest1

Insert picture description here

file type

  The two programs were executed on two systems, test0and test1both can be executed successfully on Ubuntu16 -64; test0execution failed on Ubuntu10 -32.
Insert picture description here

Execute on Ubuntu16 -64

Insert picture description here

Execute 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.

Insert picture description here

ARM64 file after compilation

  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.

Insert picture description here

Execute ARM program on X64 machine

  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.
Insert picture description here

IDE view file segment information
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-namesuch 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:
Insert picture description here

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

Guess you like

Origin blog.csdn.net/qq_20553613/article/details/106440641