前言
GDB 全称“GNU symbolic debugger”,使用GDB调试将会更加灵活。GDB占用资源少,通用性强,且可以看到一些IDE调试无法展现的东西(比如说要看一个指针引用数组的所有元素)。本人在使用vscode调试过程中发现一些需要查看一些指针数据的时候vscode就显得力不从心了,所以转向gdb调试,虽然操作麻烦一些,但是效果可观。
一、编译
-
直接编译 一般来说GDB主要调试的是C/C++的程序。要调试C/C++的程序,首先在编译时,我们必须要把调试信息加到可执行文件中。使用编译器(cc/gcc/g++)的 -g 参数可以做到这一点。如: gcc -g hello.c -o hello
g++ -g hello.cpp -o hello
要用gdb调试程序,必须在编译时加上-g和-ggdb选项,-g选项的作用是在可执行文件中加入源文件信息,但并不是将源文件嵌入可执行文件,所以在调试时必须保证gdb必须能找到源文件。-g 和 -ggdb 都是令 gcc 生成调试信息,但是二者有一些区别。 -
使用CMake编译 添加<-g3> <-gdwarf-2> 到 CMakelists.txt ,确保项目在debug模式下运行(-DCMAKE_BUILD_TYPE=Debug )。
二、GDB启动
三、TUI模式
在TUI模式中,GDB窗口划分为两个子窗口——一个用于输入GDB命令,而另一个用于查看源代码。
(gdb) layout src
(gdb) winheight src +5
(gdb) layout split
(gdb) focus cmd
(gdb) focus src
退出tui模式,使用CTRL + X + A 快捷键
四、设置断点
-
设置断点 (gdb) b test_hello:hello
(gdb) b test_hello:102
(gdb) break 2 if i == count - 1
-
查看断点 (gdb)info break [n]
-
删除断点 (gdb) delete 2
(gdb) delete
五、调试代码
run 运行程序,可简写为r
next 单步跟踪,函数调用当作一条简单语句执行,可简写为n
step 单步跟踪,函数调进入被调用函数体内,可简写为s
finish 退出进入的函数
until 在一个循环体内单步跟踪时,这个命令可以运行程序直到退出循环体,可简写为u。
continue 继续运行程序,可简写为c
六、查看运行过程中的数据
(gdb) print i
$1 = 503
(gdb) p/s str
$1 = "hello world"
(gdb) p str[0]='V'
$2 = 86 'V'
(gdb) p/s str
$3 = "vello world"
(gdb) p argv[0]@argc
(gdb) p *(int *)arr@2
$1 = {1, 2}
七、查看内存地址
x / [Length] [Format] [Modifier] [Address] Length:确定检查的个数(e.g. 14 or 9) Format:打印的格式(e.g. b, h, w or g),bytes(1 byte), half words(2 bytes), words(4 bytes), giant words(8 bytes) Modifier:输出的位数(e.g c or x or f)(c :char, x :hexadecimal, f :floating point)
(gdb) x/14bc str
0x7fffffffd7b0: 104 'h' 101 'e' 108 'l' 108 'l' 111 'o' 44 ',' 32 ' ' 119 'w'
0x7fffffffd7b8: 111 'o' 114 'r' 108 'l' 100 'd' 33 '!' 0 '\000'
(gdb) x/14bx str
0x7fffffffd7b0: 0x68 0x65 0x6c 0x6c 0x6f 0x2c 0x20 0x77
0x7fffffffd7b8: 0x6f 0x72 0x6c 0x64 0x21 0x00
(gdb) x/9gf data
0x7fffffffdb50: 1.5 2
0x7fffffffdb60: 1.5 2.2999999999999998
0x7fffffffdb70: 4 5.5
0x7fffffffdb80: 6.5999999999999996 0
0x7fffffffdb90: 7.2000000000000002
|