GDB Tutorial


撸码10分钟,DEBUG2小时。
有IDE的时候可以用IDE提供的Debugger,没有IDE的时候不能总靠printf, cout来debug,效率太低,所以好好学习一下GDB的用法。

使用GDB一定要记得在compile的时候加上-g,-g会告诉compiler不要优化代码,保留它原本的样子,只有这样,才可以一行一行去debug,知道代码问题出在哪里。

GDB overview

假如我们有一个test.cpp长这样:

#include <iostream>
#include <string>

int main(int argc, char** argv){
   
  int j = atoi(argv[1]);
  int k = atoi(argv[2]);
  j = k+3;
  k = j*k;
  std::cout << "the result is " << k << std::endl;
  return 0;
}

我们用g++ -g来编译,生成一个名为test的可执行文件:

g++ -g test.cpp -o test

load executable file into GDB

要用GDB来debug,只需要运行:

gdb ./test

这条指令会让我们可以在GDB里面运行我们的程序test

因为./test 需要两个参数,我们可以在这一步使用–args传入,比如传入参数1,2:

gdb --args ./test 1 2

也可以就像前面那样,直接载入,然后在GDB里面传入。

run program in GDB

如果前面没有使用–args传入参数的话,那么在gdb里面运行的时候,我们需要传入两个参数,然后使用指令run来执行:

(gdb) run 1 2

如果已经使用了–args传入了参数,直接使用指令run,然后开始运行载入gdb的可执行文件test:

(gdb) run  // 也可以使用简写r

这样的运行结果和不使用GDB的运行结果是一样的,我们可以得到:

(gdb) run 1 2
Starting program: /localdisk/home/test 1 2   // 程序所在位置
the result is 10   // 程序输出
[Inferior 1 (process 78344) exited normally] //程序运行状态

quit GDB

要退出GDB,只需要使用quit或者q

(gdb) quit
(gdb) q

上面几个指令只是介绍了最基本的GDB的使用方法。要真正发挥GDB的作用,我们需要学习如下指令:

GDB commands

break

break指令用于设置断点,可以给break传入你想要停止的line number,也可以给break传入你想要停止的function name, 比如:

(gdb) break main
Breakpoint 1 at 0x4011a5: file test.cpp, line 5.

会在执行到main()的时候停下来,等待进一步地指令。

(gdb) break 7
Breakpoint 2 at 0x4011d1: file test.cpp, line 7.

会在第七行停下来,等待进一步地指令。

next

当设置好断点之后,使用run开始运行程序,程序会在断点的地方停下来。如果我们想要执行下一步,就可以使用next (也可以使用简写n):

(gdb) run 1 2
Starting program: /localdisk/mdu5/test 1 2
Breakpoint 1, main (argc=3, argv=0x7fffffffd768) at test.cpp:5
5	  int j = atoi(argv[1]);
(gdb) next
6	  int k = atoi(argv[2]);

note: 当使用next的时候,打印出来的是即将执行,但是还没有被执行的code。比如上面next显示第6行,其实这一行目前还没有开始执行。

list

如果程序很长,每次使用next只会print正在执行的单行代码,让人搞不清整个程序在做些什么。这个时候就可以使用list来看看当前代码上下文:

(gdb) list
1	#include <iostream>
2	#include <string>
3	
4	int main(int argc, char** argv){
   
5	  int j = atoi(argv[1]);
6	  int k = atoi(argv[2]);
7	  j = k+3;
8	  k = j*k;
9	  std::cout << "the result is " << k << std::endl;
10	  return 0;

这样,我们就可以清楚看到,我们执行到第6行,第6行的前后代码长这样(只打印部分前后代码)。

print

如果我们想要检查程序运行过程中,某个变量的具体值,可以使用print:

(gdb) print j
$1 = 1
(gdb) print k  // 我们前面提到,line 6即将执行,但是还没有执行
$2 = 0         // 所以k的值是0,而不是2

GDB非常强大的一点在于,它不止可以print某个变量的值,甚至可以print一些表达式的值:

(gdb) n  // next 的缩写
Breakpoint 2, main (argc=3, argv=
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值