为了让我们的程序能被GDB调试,在编译的时候需要加上编译选项 -g 例如:
gcc -c -g main.c -o main.o
1. 启动GDB:
gdb main
( 该文中所有的命令均在linux的终端上实验通过。)
执行上面的命令要求当前的目录文main程序所在的目录,也可以不在main所在的目录,那样就需要指定main的路径,用绝对路径和相对路径都可以。
2. 列出代码:
l (这是小写的L)
或者是list
调试代码时, 我们肯定需要查看代码,有2中方式查看代码,一是在另外一个终端打开源代码。二是用GDB的l 命令查看。如果只是输入l 然后回车,默认是从的文件的第一行开始显示,每次显示10行。
如果想继续查看下面的代码行,可以再次输入l,然后回车会再显示10行。这里有个技巧就是如果你上次输入的命令是l,下次可以不输入任何命令,直接回车亦可以输入下面的10行代码。
如果查看某一行开始的代码, 如想查看第50开始的代码:
l 50
回车后就会看到从第50行开始的10行代码。
3. 设置断点。
调试代码时,一个几乎不可缺少的动作就是设置断点。
b 行数
break 行数
取消断点:
clear 行数
注意不可以是c 行数, 因为c是GDB的另外一个命令。
4. 让程序启动
r 或者 run
5. 单步执行
s 或者 step
一般当程序停在断点处,我们就需要单步执行了。
6. 继续执行
注意不是r 或者run, 而是c 或者continue.
7. 查看变量
p 变量名
或者print 变量名
8. 查看内存
x/nfu 内存地址
选项如下:
x 是 examine 的缩写
n表示要显示的内存单元的个数
f表示显示方式, 可取如下值
x 按十六进制格式显示变量。
d 按十进制格式显示变量。
u 按十进制格式显示无符号整型。
o 按八进制格式显示变量。
t 按二进制格式显示变量。
a 按十六进制格式显示变量。
i 指令地址格式
c 按字符格式显示变量。
f 按浮点数格式显示变量。
u表示一个地址单元的长度
b表示单字节,
h表示双字节,
w表示四字节,
g表示八字节
如:
x/3uh buf
表示从内存地址buf读取内容,
h表示以双字节为一个单位,
3表示三个单位,
u表示按十六进制显示
9. 显示调用堆栈
bt
或者 backtrace
用bt full将打印出当前堆栈中所有的变量以及变量的值。
10. 改变变量的值
set 变量名=新值
11. attach进程
attach 进程ID
12. 调试子进程
我们经常会写一些父子进程或者是daemon进程。GDB默认情况下是不会进入子进程的,即使你在自进程中设置了断点。
如果想要调试子进程,先执行
set follow-fork-mode child
然后再调试就可以进入子进程了。
你也可以通过attach进程的方式进入子进程。
13. 多线程调试
*. 在运行r(或者run)后,如果有新的线程产生,则会有提示:
[New Thread 1056688990 (LWP 12900)]
*. info threads
用这个命令来查看当前的线程的运行情况,包括当前活动的线程是哪个。活动的线程的行首有个星号。
*. thread ID,强行切换到某个线程,这里的ID是GDB给各个线程的编号,不是我们程序中创建线程时的那个ID.这个ID可以用
info threads 可以查到。
版权所有,禁止转载. 如需转载,请先征得博主的同意,并且表明文章出处,否则按侵权处理.