当前位置:   article > 正文

Linux操作系统中GDB工具的常见用法_inferior 1(process 70400)exited normally

inferior 1(process 70400)exited normally

本文主要介绍Linux操作系统中GDB(The GNU Project Debugger)工具的常见用法。

1 概述

1.1 What

引用GDB官网中的介绍,内容如下:

GDB, the GNU Project debugger, allows you to see what is going on 'inside' another program while it executes -- or what another program was doing at the moment it crashed.

GDB can do four main kinds of things (plus other things in support of these) to help you catch bugs in the act:

  • Start your program, specifying anything that might affect its behavior.
  • Make your program stop on specified conditions.
  • Examine what has happened, when your program has stopped.
  • Change things in your program, so you can experiment with correcting the effects of one bug and go on to learn about another.

Those programs might be executing on the same machine as GDB (native), on another machine (remote), or on a simulator. GDB can run on most popular UNIX and Microsoft Windows variants, as well as on Mac OS X.

2 常见用法

本章通过调试示例程序的方式,介绍GDB工具的常见用法。

2.1 示例程序1

2.1.1 源码及编译

示例程序的源代码(gdb_test1.cpp)内容如下:

  1. #include <iostream>
  2. using namespace std;
  3. int Sum(int& x, int& y)
  4. {
  5. cout << "Func Sum begin" << endl;
  6. int z;
  7. z = x + y;
  8. cout << "Func Sum end" << endl;
  9. return z;
  10. }
  11. int main()
  12. {
  13. cout << "Func main begin" << endl;
  14. int a = 1;
  15. int b = 2;
  16. int c;
  17. c = Sum(a, b);
  18. cout << "c is: " << c << endl;
  19. cout << "Func main end" << endl;
  20. return 0;
  21. }

编译上述代码,命令如下:

g++ -o gdb_test1 gdb_test1.cpp -g

注意:在编译过程中添加“-g”选项,将源代码信息添加到可执行文件中,便于后面进行gdb调试。

2.1.2 gdb调试

1. 启动gdb,命令及过程信息如下:

[root@node1 /opt/liitdar/mydemos/simples/gdb_test]<span class="hljs-comment"># gdb</span>
GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-110.el7
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 <span class="hljs-string">"show copying"</span>
and <span class="hljs-string">"show warranty"</span> <span class="hljs-keyword">for</span> details.
This GDB was configured as <span class="hljs-string">"x86_64-redhat-linux-gnu"</span>.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
(gdb) 

说明:

  • 启动gdb的命令格式为:“gdb”;
  • 启动gdb后,就可以在gdb命令行中输入gdb的调试命令了,后面介绍的gdb调试命令,都是在gdb命令行中输入并执行的。

2. 加载被调试的可执行文件,命令及过程信息如下:

(gdb) file gdb_test1
Reading symbols from /opt/liitdar/mydemos/simples/gdb_test/gdb_test1...<span class="hljs-keyword">done</span>.
(gdb) 

说明:

  • 加载被调试的可执行文件的命令格式为:“file execute_file”,其中execute_file为可执行文件名称,其路径可以为绝对路径或相对路径。

3. 设置断点(breakpoint),命令及过程信息如下:

(gdb) b main
Breakpoint 1 at 0x400923: file gdb_test1.cpp, line 17.
(gdb) 

说明:

  • 设置断点的命令格式为:“b <行号>|<函数名称>|*<函数名称>|*<代码地址>”。在本例中,通过“函数名称”设置断点的;
  • 断点编号从“1”开始递增;
  • 在设置完某一断点后,点击“Enter”键时,会在前一个断点对应的代码位置继续执行断点设置操作(即重复设置断点),同时断点编号递增,命令及过程信息如下:
    1. (gdb) b main
    2. Breakpoint 1 at 0x400873: file gdb_test1.cpp, line 17.
    3. (gdb)
    4. Note: breakpoint 1 also set at pc 0x400873.
    5. Breakpoint 2 at 0x400873: file gdb_test1.cpp, line 17.
    6. (gdb)
    7. Note: breakpoints 1 and 2 also set at pc 0x400873.
    8. Breakpoint 3 at 0x400873: file gdb_test1.cpp, line 17.
    9. (gdb)
  • 在函数名称前面加“*”表示将断点设置在“由编译器生成的prolog代码处”。建议了解相关的汇编知识后,再使用此方法设置断点。

4. 删除断点,命令及过程信息如下:

(gdb) d 1
(gdb) 

说明:

  • 删除断点的命令格式为:“d [断点编号]”;
  • 如果指定了断点编号,此操作会删除该编号对应的断点,否则,会删除所有断点;
  • 执行删除断点命令后,再次添加断点时,断点编号会(在上一个断点编号基础上)递增,即删除的断点编号不会回收。

5. 运行被调试的可执行文件,命令及过程信息如下:

【未设置断点时】:

(gdb) r
Starting program: /opt/liitdar/mydemos/simples/gdb_test/gdb_test1 
Func main begin
Func Sum begin
Func Sum end
c is: 3
Func main end
[Inferior 1 (process 7432) exited normally]
(gdb) 

【设置断点时】:

(gdb) r
Starting program: /opt/liitdar/mydemos/simples/gdb_test/gdb_test1 

Breakpoint 2, main () at gdb_test1.cpp:17
17	    cout << <span class="hljs-string">"Func main begin"</span> << <span class="hljs-string">endl;
(gdb) </span>

说明:

  • 运行被调试的可执行文件的命令格式为:“r”;
  • 如果没有设置过断点,则执行完整程序;如果已经设置了断点,则程序运行到第一个可用的断点处暂停。在本例中,分别展示了设置断点和未设置断点的情况。

6. 继续执行被调试程序,命令及过程信息如下:

(gdb) c
Continuing.
Func main begin
Func Sum begin
Func Sum end
c is: 3
Func main end
[Inferior 1 (process 7548) exited normally]
(gdb) 

说明:

  • 继续执行被调试程序的命令格式为:“c”;
  • 此操作会继续执行被调试程序,直至下一个断点或程序结束。在本例中,由于后面没有断点了,所以完整程序执行结束。

7. 执行一行调试程序源码(如果此行代码中有函数调用,则会进入该函数中,继续一次一行地执行该函数的代码,命令及过程信息如下:

(gdb) s
23	    c = Sum(a, b);
(gdb) 
Sum (x=@0x7fffffffe498: 1, y=@0x7fffffffe494: 2) at gdb_test1.cpp:7
7	    cout << <span class="hljs-string">"Func Sum begin"</span> << <span class="hljs-string">endl;
(gdb) </span>

说明:

  • 执行一行调试程序源码(每次一行执行调用的函数语句)的命令格式为:“s”;
  • 此操作用于执行一行源程序代码,如果此行代码中有函数调用,则会进入该函数中,继续一次一行地执行该函数的代码。在本例中,执行到23行时,由于该行存在函数调用语句“c = Sum(a, b);”,所以在执行该行代码时,程序流程进入了Sum函数中,后面每个“s”操作,都会继续执行Sum函数的每一行代码;
  • 此操作相当于其它调试器中的“Step Into(单步跟踪进入)”;
  • 此操作必须在程序包含源代码调试信息的情况下才可以使用(gcc编译时使用“-g”参数)。

8. 执行一行调试程序源码(如有函数调用,会执行该函数的所有内容),命令及过程信息如下:

(gdb) n
23	    c = Sum(a, b);
(gdb) 
Func Sum begin
Func Sum end
24	    cout << <span class="hljs-string">"c is: "</span> << <span class="hljs-string">c << endl;
(gdb) 
</span>

说明:

  • 执行一行调试程序源码(一次执行完成所有的调用的函数语句)的命令格式为:“n”;
  • 此操作用于执行一行源程序代码,如果此行代码中有函数调用,则执行该函数的所有内容。在本例中,执行到23行时,由于该行存在函数调用语句“c = Sum(a, b);”,所以在执行该行代码时,函数Sum的全部内容都被执行了;
  • 此操作相当于其它调试器中的“Step Over(单步跟踪)”;
  • 此操作必须在程序包含源代码调试信息的情况下才可以使用(gcc编译时使用“-g”参数);
  • 在执行“s”或“n”操作时,gdb显示出来的代码是当前执行到的代码位置,而实际上该行代码尚未执行。例如,本例中第一个n操作后,gdb中显示了“23     c = Sum(a, b);”内容,但此时该行(即23行)代码尚未执行(可通过打印“c”的值证实)。

9. 打印变量的值,命令及过程信息如下:

(gdb) n
Func main begin
19	    int a = 1;
(gdb) 
20	    int b = 2;
(gdb) 
23	    c = Sum(a, b);
(gdb) p c
<span class="hljs-variable">$19</span> = 0
(gdb) n
Func Sum begin
Func Sum end
24	    cout << <span class="hljs-string">"c is: "</span> << <span class="hljs-string">c << endl;
(gdb) p c</span>
<span class="hljs-variable">$20</span> = 3
(gdb) 

说明:

  • 打印变量的值的命令格式为:“p <变量名称>”;
  • 此操作用于打印指定变量(临时变量或全局变量)的值。在本例中,打印了变量“c”的值。

3 常见问题

3.1 Missing separate debuginfos

在运行gdb时,如果遇到此问题,说明系统中缺少debug信息,此问题的错误信息后面通常都会给出问题解决方法,如下:

Missing separate debuginfos, use: debuginfo-install glibc-2.17-196.el7_4.2.x86_64 libgcc-4.8.5-16.el7_4.2.x86_64 libstdc++-4.8.5-16.el7_4.2.x86_64

1. 根据提示的问题解决方法,运行相关的命令,操作如下:

[root@node1 /opt/liitdar/mydemos/simples/gdb_test]<span class="hljs-comment"># debuginfo-install glibc-2.17-196.el7_4.2.x86_64 libgcc-4.8.5-16.el7_4.2.x86_64 libstdc++-4.8.5-16.el7_4.2.x86_64</span>
Loaded plugins: fastestmirror
enabling epel-debuginfo
epel-debuginfo/x86_64/metalink                                                                                                                                                                                       | 7.0 kB  00:00:00     
epel-debuginfo                                                                                                                                                                                                       | 1.5 kB  00:00:00     
epel-debuginfo/x86_64/primary                                                                                                                                                                                        | 503 kB  00:00:02     
Loading mirror speeds from cached hostfile
 * base: mirrors.aliyun.com
 * epel: mirror01.idc.hinet.net
 * epel-debuginfo: mirror01.idc.hinet.net
 * extras: mirrors.aliyun.com
 * updates: mirrors.aliyun.com
epel-debuginfo                                                                                                                                                                                                                    2783/2783
Could not find debuginfo <span class="hljs-keyword">for</span> main pkg: glibc-2.17-196.el7_4.2.x86_64
Could not find debuginfo pkg <span class="hljs-keyword">for</span> dependency package nss-softokn-freebl-3.28.3-8.el7_4.x86_64
Could not find debuginfo <span class="hljs-keyword">for</span> main pkg: libgcc-4.8.5-16.el7_4.2.x86_64
Could not find debuginfo <span class="hljs-keyword">for</span> main pkg: libstdc++-4.8.5-16.el7_4.2.x86_64
No debuginfo packages available to install
[root@node1 /opt/liitdar/mydemos/simples/gdb_test]<span class="hljs-comment"># </span>

2. 运行“debuginfo-install”命令,安装debug信息时,提示找不到debuginfo包,这是因为yum源中没有配置debuginfo、或者未打开debuginfo源的开关。所以,首先需要保证yum源中的debuginfo配置可用。本文中使用的yum配置文件(CentOS-Base.repo)中的debuginfo相关信息如下:

<span class="hljs-comment">#Debug Info</span>
[debuginfo]
name=CentOS-<span class="hljs-variable">$releasever</span> - DebugInfo
baseurl=http://debuginfo.centos.org/<span class="hljs-variable">$releasever</span>/<span class="hljs-variable">$basearch</span>/
gpgcheck=0
enabled=1

说明:

  • 上述yum配置信息可以添加到“/etc/yum.repos.d/CentOS-Base.repo”中,或新增的一个文件,例如“/etc/yum.repos.d/CentOS-Debug.repo”;
  • CentOS官方对于debuginfo的描述:debuginfo - Packages with debugging symbols generated when the primary packages were built. No repo config is provided by default. Tools like oprofile, crash, and systemtap require debuginfo packages. Note that debuginfo packages may not be signed so must be installed with "--nogpgcheck" or using "gpgcheck=0" in the repo definition. These packages are found at http://debuginfo.centos.org/

3. 配置完yum源后,更新yum缓存;

4. 再次运行前面的gdb提示命令(内容如下),此时即可成功安装debuginfo信息了。

debuginfo-install glibc-2.17-196.el7_4.2.x86_64 libgcc-4.8.5-16.el7_4.2.x86_64 libstdc++-4.8.5-16.el7_4.2.x86_64

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/天景科技苑/article/detail/742362
推荐阅读
相关标签
  

闽ICP备14008679号