本章讲解知识点

    1. GDB 指令入门
    1. GDB 指令学习
    1. 使用华为云远程服务器学习 GDB

  • 本专栏适合于软件开发刚入职的学生或人士,有一定的编程基础,帮助大家快速掌握工作中必会的工具和指令
  • 本专栏针对面试题答案进行了优化,尽量做到好记、言简意赅
  • 如专栏内容有错漏,欢迎在评论区指出或私聊我更改,一起学习,共同进步。
  • 相信大家都有着高尚的灵魂,请尊重我的知识产权,未经允许严禁各类机构和个人转载、传阅本专栏的内容。

1. GDB 指令入门

经过前面的铺垫,终于到讲指令了呀,家人们,撒花撒花~ ~ ~

为了能够使用 GDB 调试我们的执行程序,需要重新编译一下,加上参数 -g

$ gcc -g douya.c -o douya

参数 -g 会为我们的调试文件加上必要的行信息。这样我们就可以查看。

我们进入 GDB 调试:

$ gdb douya

GNU gdb (GDB) 10.1
Copyright (C) 2020 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-w64-mingw32".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://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 douya...
(gdb)

我们通过查看命令 list 可以查看程序内容:

(gdb) list

1       #include <stdio.h>
2
3       int main(){
4               int i = 0;
5               int temp = 1;
6
7               for (i; i <= 10; i++){
8                       temp *= i;
9                       printf("hello douya!\n");
10              }
(gdb)

可以看出,GDB 为我们的调试文件加入了必要的行信息。

我们运行程序, 命令 rrun 就是运行程序:

(gdb) r

hello douya!
hello douya!
hello douya!
hello douya!
hello douya!
hello douya!
hello douya!
hello douya!
hello douya!
hello douya!
hello douya!
[Inferior 1 (process 8012) exited normally]
(gdb)

然后我们通过命令 qquit 退出调试。

(gdb) quit

好了,我们已经成功完成了 GDB 调试一个程序,大家已经 GDB 入门了,好了,今天我们的教程就到这里了,再见!


算了,开玩笑的啦。摊手,我们继续吧。


2. GDB 指令学习

2.1. 设置断点

我们进入调试,然后在程序第 4 行设下【断点】,使用指令 bbreak

$ gdb douya
(gdb) b 4

Breakpoint 1 at 0x40159e: file douya.c, line 4.

也可以为某个函数打下断点,如:

(gdb) b main

我们 r 运行至断点

(gdb) r

Breakpoint 1, main () at douya.c:4
4               int i = 0;

可以看到,程序成功运行至第 4 行了,并且打印出了相关信息。

接下来我们想单步运行程序,通过指令 nnext 实现:

(gdb) n
5               int temp = 1;

现在我们不想单步了,想运行到下一个断点,那我们先在第 12 行设置一个新断点:

(gdb) b 12
Breakpoint 2 at 0x4015d1: file douya.c, line 12.

然后运行 ccontinue

(gdb) continue
Continuing.

Breakpoint 2, main () at douya.c:12
12              return 0;

好的,我们成功做到了,各位家人们!太棒了!

我们可以通过 info 命令查看断点信息:

(gdb) info b
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x000000000040159e in main at douya.c:4
        breakpoint already hit 1 time
2       breakpoint     keep y   0x00000000004015d1 in main at douya.c:12
        breakpoint already hit 1 time

我们也可以通过条件断点,比如我想在 i=3 的时候让程序停在第 8 行:

(gdb) b 8 if i=3
Breakpoint 4 at 0x4015ae: file douya.c, line 8.

(gdb) r
Breakpoint 1, main () at douya.c:4
4               int i = 0;
(gdb) c
Continuing.

Breakpoint 4, main () at douya.c:8
8                       temp *= i;

可以看到现在程序停在了第 8 行。

我们可以通过指令 cleardelete 来删除断点。

(gdb) info breakpoint
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x000000000040159e in main at douya.c:4
        breakpoint already hit 1 time
4       breakpoint     keep y   0x00000000004015ae in main at douya.c:8
        stop only if i=3
5       breakpoint     keep y   0x00000000004015d1 in main at douya.c:12

(gdb) clear 12
Deleted breakpoint 5

clear 12 删除了第 12 行的断点。

(gdb) delete

(gdb) info b
No breakpoints or watchpoints.

delete 删除了所有的断点。

我们也可以禁止使能断点,分别对应指令 disableenable

(gdb) b 4   // 设置断点
Breakpoint 6 at 0x40159e: file douya.c, line 4.
(gdb) b 8   // 设置断点
Breakpoint 7 at 0x4015ae: file douya.c, line 8.
(gdb) b 12   // 设置断点
Breakpoint 8 at 0x4015d1: file douya.c, line 12.
(gdb) info b     // 查看断点
Num     Type