gdb是一款UNIX及UNIX-like下的调试工具
gdb可用于调试用gcc编译的可执行文件,用gdb调试时gcc编译需要使用参数-g
本文是对于gdb在Linux下使用的基本命令的总结gdb调试视频演示,gdb调试基础指令,gdb调试其他命令,gdb常见错误说明
编辑
目录
编辑
gdb调试视频演示
视频中使用gdb调试一个文件,下面有视频中命令的介绍,帮助大家直观理解一下GDB调试
GDB调试
视频中
l是list,列出代码
可以看出每行代码有行号,需要b+行号命令,给程序打断点,这样程序就会停止在断点位置
打好断点后,使用run命令,程序将运行到断点处停下来
我们可以从断点开始一行一行执行代码
两种单步运行命令
s是step,如果一行代码是函数的话,会进入函数
n是next,如果这一行代码是函数的话,不会进入这个函数,会运行本函数的下一条命令
continue可以运行断点之后的命令
我们这样断点调试一个程序,就是为了查看一下程序在运行过程中变量存储的数值,可以使用命令p+变量,打印变量在运行过程中存储的值
quit命令可以退出调试
gdb调试基础指令
1.gcc检查语法错误
2.-g 使用该参数编译可以执行文件,得到调试表
gcc -g main.c -o main(加了-g才能用gdb)
3.gdb检查逻辑错误
4.gcc 文件名.c -o gdbtest
5.gcc 文件名.c -o gdbtest2 -g
6.gcc gdbtest.c -o a.out -g 编译
gdb a.out 进入调试
在(gdb)后面加“l”或者“list”
在(gdb)后面加“list 1”,使得从第一行开始显示十行,再在(gdb)后面再写”l“,会出现后续的行
7.设置断点
在gdb后面输入“break”和“b”
e.g
b 52
8.(gdb)后输入run,执行程序到断点处,断点处语句没有执行
(gdb)后面输入“s”或“step”,下一条命令,不会越过函数
(gdb)后面输入“n”或“next”,下一条命令,会越过函数
9.如果函数是系统函数只能用“n“,不能用”s”
10.until 循环次数 可以退出循环
11.p 变量
print 变量
可以查看变量
12.continue
继续执行断点后续命令
13.quit:退出gdb当前调试
gdb调试其他命令
1.用gdb调试查找段错误出现位置
段错误是访问了不可访问的内存
用gdb打开一个程序,直接“run”,程序停下的位置就是段错误的位置
2.start
默认从当前程序第一行开始运行
3.finish 可以结束当前函数调用,回到函数的调用点
4.set args 设置main函数命令行参数
可以有带参数的main函数,在“./文件名”后面加上参数
在(gdb)后面加上“set args 参数 参数”(要设置在start之前),可以加入参数
5.run 参数 参数2,设置main函数参数
6.display
display命令查看变量或表达式的值,每当程序暂停执行(例如单步执行)时,GDB 调试器都会自动帮我们打印出来,而 print 命令则不会。
7.info b 查看断点信息
8.条件断点:b 行号 if 变量=数据
e.g b 20 if i=5
一般用于循环
9.ptype 变量 查看变量类型
在子函数中不能查看没有通过参数传入子函数的变量
10.栈里面存放栈帧
栈帧是随着函数调用而在stack上开辟的一片内存空间,用于存放函数调用时时产生的局部变量和临时值
kernel(内核数据) |
环境变量,main参数 |
stack(栈) |
.so加载位置 |
heap(堆) |
.bss |
.data |
.rodata(只读数据段) |
.text(代码段) |
有一个函数调用就会产生一个栈帧,调用结束,栈帧消失
如果想彻底理解栈帧有关机制的话,可以学习一下汇编语言
调用子函数main函数的栈帧不会消失,因为main函数没有结束
子函数栈帧中有形参和局部变量,子函数调用结束,子函数栈帧消失
11.利用指针可以在一片栈帧去修改另一片栈帧的值
12.backtrace:查看函数调用的栈帧和层级关系
frame:根据栈帧编号切换栈帧
bt:查看栈帧(#后面的是栈帧号)
frame 栈帧号
13.display 变量 设置跟踪变量
undisplay 变量 取消设置跟踪变量
gdb常见错误说明
常见错误
编译没有加“-g”
用gdb打开文件
list会出现 没有符号被读取,请使用“file”命令
解决方法
1.quit,重新编译
2.file a.out(a.out必须经过gdb调试)