一文入门Linux下gdb调试(一)

作者:良知犹存

转载授权以及围观:欢迎添加微信号:Conscience_Remains

总述

    在window下我们习惯了IDE的各种调试按钮,说实话确实挺方便的,但到了Linux下,没有那么多的IDE支持我们调试,但是Linux有也有强大的命令行C/C++的调试工具——GDB,GNU提供的开源调试工具。

    刚开始不习惯,使用多了我们就会喜欢上他,程序调试的单步执行,跳入函数,跳出函数,设置断点,设置观察点,查看变量。GDB都有,此外gdb还可以生成程序非法执行后core dump文件,这个文件有快照功能,在程序崩溃的时候保存了程序的堆栈等信息,我们执行core文件就可以方便的找程序崩溃的原因了。

 

一、编译可以调试的代码

    在linux下对於单个c/c++文件编译通常就是加-o 进行编译成可执行文件,但是我们如果需要要调试,则需要加一个 -g 用来向编译器进行表明该程序需要编译成可以gdb调试的代码,加上编译信息,生成的执行文件就会变大,如图所示。所以我们只在调试的时候进行 -g 编译。Java调试的时候也是类似后续也说一哈java的Linux。

 

 

 

Makefile的文件中我们也是如上,只不过是在Makefile文件中 -o 编译的时候添加 -g

 

 

 

 

二、调试过程

调用gdb调试,先查看电脑环境里面是否有gdb调试器,一般我们安装了gcc编译器,就默认同时安装了gdb调试器

 

没有的话要安装gdb调试器,使用apt-get 就可以快速安装

apt-get updateapt-get install  gdb

 

gdb 调用执行文件 

gdb ./big_endian /*执行文件*/

 

最基本的GDB命令

 

 

命令 全称 解释
l list 查看源码
b break 设置断点
r run 运行程序,在断点处停止
n next 单条语句执行
c continue 继续运行程序,下一个断点处停止 
p print 打印 变量信息
q quit 退出GDB

 

delete  delete  删除断点
disp  display   跟踪查看某个变量,每次停下来都显示它的值  
st    start    开始执行程序,在main函数的第一条语句前面停下来
watch  watch  监视变量值的变化
file   file   装入需要调试的程序
bt    backtrace  查看函数调用信息(堆栈)  
 f frame      查看栈帧 f n 切换到编号为n的栈
undisp (数字) undisplay  取消显示
help help 帮助命令
set (args 10 20 30 40 50 )   可指定运行参数
s step 执行到函数内部

 

 

示例执行:

/*刚开始有很多打印的信息*/book@lyn:~/Documents/linux/test/wds/wds_c++/c++_test1/c11th$ gdb person1GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1Copyright (C) 2016 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-linux-gnu".Type "show configuration" for configuration details.For bug reporting instructions, please see:<http://www.gnu.org/software/gdb/bugs/>.Find the GDB manual and other documentation resources online at:<http://www.gnu.org/software/gdb/documentation/>.For help, type "help".Type "apropos word" to search for commands related to "word"...Reading symbols from person1...done.(gdb) l 10  /*list 10  显示10行代码 方便下一步打断点调试*/5       using namespace std;67       class Person {8       private:9               static int cnt;10              char *name;11              int age;1213      public:14(gdb)   /*不输入 直接 Enter 键 重复上一步骤*/15              static int getCount(void); 1617              Person() {//cout <<"Pserson()"<<endl;18                      name = NULL;19                      cnt++;20              }21              Person(char *name) 22              {23                      //cout <<"Pserson(char *)"<<endl;24                      this->name = new char[strlen(name) + 1];(gdb) 25                      strcpy(this->name, name);26                      cnt++;27              }2829              Person(char *name, int age) 30              {31                      cout <<"Pserson(char*, int), name = "<<name<<", age= "<<age<<endl;32                      this->age = age;3334                      this->name = new char[strlen(name) + 1];(gdb) /*......*/......9596      int main(int argc, char **argv)97      {98              Student p;99              p.setName("zhangsan");100             p.setAge(16);101             p.printInfo();102103             return 0;104     }(gdb) b 99 /*在显示的 第 99行代码处 打断点*/Breakpoint 1 at 0x400b5d: file person.cpp, line 99.(gdb) i b /*显示 设置的断点*/Num     Type           Disp Enb Address            What1       breakpoint     keep y   0x0000000000400b5d in main(int, char**) at person.cpp:99(gdb) r  /*开始全速执行代码 直到第一个断点处*/Starting program: /home/book/Documents/linux/test/wds/wds_c++/c++

 

Breakpoint 1, main (argc=1, argv=0x7fffffffe3d8) at person.cpp:9999              p.setName("zhangsan");(gdb) p p  /*打印 p 变量信息*/$1 = {<Person> = {static cnt = 1, name = 0x0, age = 0}, <No data fields>}(gdb) n  /*执行下一步*/100             p.setAge(16);(gdb) q  /*退出 gdb 调试*/A debugging session is active.        Inferior 1 [process 3410] will be killed.Quit anyway? (y or n) y

 

(gdb) i disp  /*显示所有的disp变量*/Auto-display expressions now in effect:Num Enb Expression1:   y  ap2:   y  * ap3:   y  *ap4:   y  val(gdb) undisplay 1 /*取消显示第一个变量*/(gdb) undisplay 2(gdb) undisp 3(gdb) i disp /*查看确认*/Auto-display expressions now in effect:Num Enb Expression4:   y  val

 

(gdb) shanoi (n=3, x=120 'x', y=121 'y', z=122 'z') at Hanoi.c:2121              if(n==1)                                                        //欲移动n个圆盘,需先移动其上的n-1个圆盘 (gdb) n25                      hanoi(n-1, x, z, y);                    //将x上编号为1至n-1的圆盘移到y,z作辅助塔 

 

 

 这就是我分享的gdb调试一些方法,里面代码是实践过的,如果大家有什么更好的思路,欢迎分享交流哈。

 

 

更多分享,扫码关注我

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章