一、GDB概论
gdb是GNU debugger的缩写,是编程调试工具。
UNIX及UNIX-like(Linux)下的调试工具。或许,各位比较喜欢那种图形界面方式的,像VC、BCB等IDE的调试,但如果 你是在 UNIX平台下做软件,你会发现GDB这个调试工具相比于VC的优点是具有修复网络断点以及恢复链接等功能,比BCB的图 形化调试器有更强大的功能。所谓"尺有所短,寸有所长"就是这个道理。
只有在编译程序时加了-g选项,才能用gdb工具进行调试。
二、错误分类
(1)编译错误:编写程序的时候没有符合语言规范导致编译错误。比如:语法错误。编译报错会明确显示哪一行出现了什么错 误,这些错误的解决方案一般来说都是比较固定的,当你写的代码够多,遇到次数多了以后,你一眼就能知道为什么自己写的程 序编译通不过,这就是经验。
(2)运行时错误:编译器检查不出这种错误,但在运行时候可能会导致程序崩溃。比如:内存地址非法访问。这个时候我们可 以借助调试工具来快速定位程序的问题,而不是一行一行去看代码,也不是在程序中加很多的printf语句查看信息。总而言之,在 实际开发过程中,这是你必需具备的能力。
(3)逻辑错误:编译和运行都很顺利,但是程序没有按照我们期望来执行程序。这个时候我们也要定位问题,bug出现在什么 地方。
三、功能
一般来说,GDB主要帮助你完成下面五个方面的功能:
1、启动你的程序,可以按照你的自定义的要求随心所欲的运行程序。
2、可让被调试的程序在你所指定的调置的断点处停住。(断点可以是条件表达式)
3、当程序被停住时,可以检查此时你的程序中所发生的事 即挂载调试。
4、你可以改变你的程序,将一个BUG产生的影响修正从而测试其他BUG。
5、当程序产生核心段错误时,可以进行CORE文件调试,查找错误。
四、使用 启动调试(前提条件,编译代码时有 -g 选项)
(1) 用gdb启动程序进行调试
gdb a.out
(2) 挂载调试
ps aux | grep a.out --找到进程pid
sudo gdb a.out pid --pid为进程具体的数字id
(3)程序核心已转储(段错误)
gdb a.out -c core
在程序崩溃时,一般会生成一个文件叫core文件。core文件记录的是程序崩溃时的内存映像,并加入调试信息,core文件生 成过程叫做core dump(核心已转储)。系统默认不会生成该文件。只需要简单设置即可看到core文件。
设置生成core文件
ulimit -c:查看core-dump状态。
ulimit -c xxxx:设置core文件的大小。
ulimit -c unlimited:core文件无限制大小。
配置corefile的参数:
echo 2 > /proc/sys/fs/suid_dumpable [程序中切换用户,也要产生corefile]
mkdir /tmp/corefiles
chmod 777 /tmp/corefiles
echo “/tmp/corefiles/core”>/proc/sys/kernel/core_pattern //配置core文件产生的目录 为/tmp/corefiles
echo “1” > /proc/sys/kernel/core_uses_pid
注意:
a.确保配置的目录有足够的磁盘空间,否则产生core文件可能不完整。
b.对于mysqld而言,要保证正确产生core-file,需要加上–core-file,默认这个参数是不打开的。 c.kill -9 pid 是不能产生core文件的,因为SIGKILL信号不能被捕获。
附:
gdb 直接启动gdb,之后用file program加载程序
gdb program 普通调试
gdb program -c core 调试core
sudo gdb program pid 挂载调试 程序正在运行 得用sudo权限
sudo gdb attach pid dump已经运行进程的状态信息
如: gdb attach pid
(gdb) generate-core-file 调试完毕后,通过detach命令退出。
另外,通过gcore pid命令也可以dump core文件,生成在当前目录下
五、命令
1、运行程序
run(r)运行程序,如果要加参数,则是run arg1 arg2 …
2、查看源代码
list(l):查看最近十行源码
list fun:查看fun函数源代码
list file:fun:查看flie文件中的fun函数源代码
3、设置断点与观察断点
break 行号/fun设置断点。
break file:行号/fun设置断点。
break if:条件成立时程序停住。
info break(缩写:i b):查看断点。
watch expr:一旦expr值发生改变,程序停住。
delete n:删除断点。
4、单步调试
continue(c):运行至下一个断点。
step(s):单步跟踪,进入函数,类似于VC中的step in。
next(n):单步跟踪,不进入函数,类似于VC中的step out。
finish:运行程序,知道当前函数完成返回,并打印函数返回时的堆栈地址和返回值及参数值等信息。
until:当厌倦了在一个循环体内单步跟踪时,这个命令可以运行程序知道退出循环体。
5、查看运行时数据
print(p):查看运行时的变量以及表达式。
ptype:查看类型。
print array:打印数组所有元素。
print *array@len:查看动态内存。len是查看数组array的元素个数。
print x=5:改变运行时数据。
命令 | 命令缩写 | 命令说明 |
---|---|---|
list | l | 显示多行源代码 list lineNum |
break | b | 设置断点,程序运行到断点的位置会停下来 |
info | i | 描述程序的状态 |
thread | info threads 查看线程 |
|
run | r | 开始运行程序 |
display | disp | 跟踪查看某个变量,每次停下来都显示它的值 |
step | s | 执行下一条语句,如果该语句为函数调用,则进入函数执行其中的第一条语句 |
next | n | 执行下一条语句,如果该语句为函数调用,不会进入函数内部执行(即不会一步步地调试函数内部语句) |
p | 打印内部变量值 |
|
continue | c | 设置 |
start | st | 开始执行程序,在main函数的第一条语句前面停下来 |
file | st | 装入需要调试的程序 |
kill | st | 开始执行程序,在main函数的第一条语句前面停下来 |
watch | k | 监视变量值的变化 |
catch | catch + event 当event发生时,程序停住 |
|
handle | st | handle + [argu] + signals |
backtrace | bt | 产看函数调用信息(堆栈) |
frame | f | 查看栈帧 |
quit | q | 退出GDB环境 |
whatis | 显示变量的类型 |
|
ptype | 比whatis功能更强,可以提供一个结构的定义 |
|
examine | examine /n f u + 内存地址 (指针变量) |
|
call | 调用函数 |