Gdb debugging information and debugging principle

    For C++ program development under Linux, even if compiling tools such as makefile and cmake are used, the compiler tool group gcc is ultimately invoked . The tool set mentioned here is because there is still a little difference between the compiler tools used to compile C programs and C++ programs. Generally , gcc is used to  compile C programs and g++ is used to compile C++ programs  . (For the convenience of the description below, unless otherwise specified, no specific distinction is made between gcc and g++, and the term gcc is used uniformly.)

The operating system I use in this course is CentOS 7.0, which is a root account demonstration for the convenience of demonstration. If gcc and gdb are not installed on the reader's machine, you can use the  yum  command to install them.

# 安装 gcc
yum install gcc
# 安装 g++
yum install gcc-c++
# 安装 gdb
yum install gdb

copy

Generally, a program needs to be debugged. In order to clearly see the information of each line of code being debugged, called stack information, variable names and function names, the debugger needs to contain debugging symbol information. When using  gcc to  compile a program, if the -g  option is added  , the debugging symbol information can be retained in the compiled program. For example, the following command will generate a program hello_server with debugging information.

gcc -g -o hello_server hello_server.c

copy

So how to judge whether hello_server contains debugging information? We use gdb to debug this program, gdb will display the debugging information of the program correctly read, enter gdb hello_server in the open Linux Shell terminal to   view the displayed results:

[root@localhost testclient]# gdb hello_server
GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-100.el7_4.1
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /root/testclient/hello_server...done.
(gdb)

copy

After gdb is successfully loaded, the following information will be displayed:

Reading symbols from /root/testclient/hello_server...done.

copy

That is, the completion of reading the symbol file indicates that the program contains debugging information. Let's  try again without the  -g option:

[root@localhost testclient]# gcc -o hello_server2 hello_server.c
[root@localhost testclient]# gdb hello_server2
GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-100.el7_4.1
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /root/testclient/hello_server2...(no debugging symbols found)...done.
(gdb)

copy

Careful readers should see the difference. When  using gdb to debug and generate the hello_server 2 program without the  -g option, the following prompt will be received when reading the debugging symbol information:

Reading symbols from /root/testclient/hello_server2...(no debugging symbols found)...done.

copy

By the way, in addition to not adding the -g option, you can also use the Linux strip command to remove the debugging information in a program. Let's try the strip command on hello_server:

[root@localhost testclient]# strip hello_server
##使用 strip 命令之前
-rwxr-xr-x. 1 root root 12416 Sep 8 09:45 hello_server
##使用 strip 命令之后
-rwxr-xr-x. 1 root root 6312 Sep 8 09:55 hello_server

copy

It can be found that after using the strip command on hello_server, the program is significantly smaller (reduced from 12416 bytes to 6312 bytes). We usually release the program to the production environment or the formal environment after the program is tested without any problems, so the program without debugging symbol information is generated to reduce the size of the program or improve the efficiency of program execution.

Let's use gdb to verify that the debugging information of this program is indeed removed:

[root@localhost testclient]# gdb hello_server
GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-100.el7_4.1
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /root/testclient/hello_server...(no debugging symbols found)...done.
(gdb)

copy

Two additional explanations:

  • Although gcc is used as an example in this course, the -g option is actually also applicable to Linux programs compiled with tools such as makefile and cmake.
  • When actually generating a debugger, generally not only the -g option should be added, but it is also recommended to turn off the program optimization option of the compiler. The compiler's program optimization options generally have five levels, from O0 to O4 (note that the first O0 is the letter O plus the number 0), O0 means no optimization, from O1 to O4 the optimization level is getting higher and higher, and O4 is the highest . The purpose of this is for debugging, the debugging variables displayed in the symbol file can be completely corresponding to the source code. For example, suppose the following code:
  int func()
  {
      int a = 1;
      int b = a + 1;
      int c = a + b;
      return a + b + c;
  }

  int main()
  {
      int a = func();
      printf("%d\n", a);
  }

copy

In this code, because the func() function is called in the main() function, the value of the func() function can be directly calculated during compilation. If the optimization option is turned on, the local variables in this function are actually debugged. a, b, and c are replaced by direct values ​​(that is, the value calculated by the compiler, a is directly used as 1, b is directly used as 2, and c is directly used as 3, which will not result in calculating b by a and c by a and b Instruction), even the function func() may be optimized away. If this happens, there may be differences between the code displayed by the debugger and the actual code, which will cause difficulties in troubleshooting. Of course, whether the optimization phenomenon mentioned above will definitely occur, different versions of the compiler may have different behaviors. In a word, it is recommended to turn off compiler optimization options when generating debug files .

summary

This lesson mainly introduces the installation of tools such as gdb and the importance of debugging symbols for debugging. At the same time, attention should be paid to the impact of compiler optimization options on the correctness of debugging.

Guess you like

Origin blog.csdn.net/weixin_38293850/article/details/107974741