作者:良知犹存
转载授权以及围观:欢迎添加微信号: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 | 打印 变量信息 | |
| 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调试一些方法,里面代码是实践过的,如果大家有什么更好的思路,欢迎分享交流哈。

更多分享,扫码关注我
转载:https://blog.csdn.net/lyn631579741/article/details/106867692