一。GDB基本使用方法
GDB调试程序myprog:
1. 进入GDB并调入程序
$ gdb myprog
(gdb)
2. 设置程序参数
假设程序执行方式为
./myprog -t 1 file1.txt
则在gdb中设置程序输入参数:
(gdb) set args -t 10 file1.txt
3. 在gdb中运行程序
(gdb) run
二。GDB工作原理及调试准备工作
使用GDB之前先要通过编译器产生带有调试指示的汇编代码,GDB利用这些调试代码
进行调试工作。调试代码有多种格式:STABS,DWARF,COFF,XCOFF。一些编译器可
以指定生成那种调试格式。以STABS为例,它所加入的汇编调试指示是具有下述形式
的汇编代码:
.stabn type,other,description,value
为了产生带调试代码的汇编程序,在调用GCC时需要加上调试选项命令,比如 -g,
或-ggdb,或-gstabs等。
.gdbinit 文件中保存每次启动都要执行的命令。
比如,假如在每次使用GDB时都要使用参数 a b c,可以在该文件中设置:
set args a b c
三。GDB以为程序调试提供的帮助:
1) 单步执行,设置断点,观察变量,分析函数调用;
2) 显示程序发生存储访问错误等不正常中断时的出错位置;
3) 辅助分析发生无穷循环的程序段;
1) 基本调试命令
step : 执行原程序的一个语句。该语句对应于汇编代码的多条语句,这些语句一
次执行。当遇到函数调用时,进入该函数体执行;
next:与step类似,但遇到函数调用时,不进入函数体,把函数调用一次执行;
stepi: 与step类似,但只执行一条汇编指令;
nexti:与next类型,但只执行一条汇编指令;
until : 《地址》运行到指定地址,比如 until file1:100,该命令可用于跳过循环。
目前程序调试只能向前不能退后,后退调试(reversible debug)功能正在开发当中。
break:设置程序断点,
break
:在指定的文件和行号上设置断点;
break <函数>:在指定函数调用开始处设置断点;
finish: 将中断的程序执行到结束;
kill:结束程序的执行;
continue:继续程序的执行;
Ctrl-C:强制中断程序的执行,相当于把当前点设置为breakpoint;
display: 设置某变量在每次 step,next 操作是均显示;
print:显示当前函数中一个变量的当前值;
print :: : 显示指定函数中一个变量的值;
ptype:显示变量类型;
where: 显示当前行号和当前行;
list : 显示当前点附近的原程序,
list m,n: 列出m行和n行之间的程序;
list <文件名>:<函数名>列出指定文件中的函数;
set listsize = n: 改变list所列程序的缺省行数;
shell <命令>: 执行操作系统命令;
2)为Segment Fault错定位
在出现 Segment Fault错之后,系统将产生一个core dump文件,在启动GDB时把执行程序文件同这个core文件同时作为参数,在进入GDB之后就会立即显示出错位置。
下面通过一个示例程序说明具体操作方法: (对*nowhere的赋值产生存储访问错)
/* falldown.c */
char **nowhere;
void setbad();
int main(int argc,char *argv[])
{
setbad();
printf("%s\n", *nowhere);
}
void setbad()
{
nowhere = 0;
*nowhere = "This is a string";
}
$ gcc -g falldown.c -o falldown
$ ./falldown
Segmentation fault (core dumped)
$ gdb falldown core
......
#0 0x004010aa in setbad () at falldown.c:15
15 * nowhere = "This is a string"
GDB 显示出了出错点的函数和行号.
注意:在缺省的 cygwin 环境下出错时并不产生 core 文件,而是产生一个stackdump文件,该文件所含信息比core文件少,不能当作core文件使用.为了产生影响真正的core文件,可以使用下述命令。
# generate core dump
export CYGWIN="$CYGWIN error_start=dumper -d %1 %2"
对上面的例子,操作过程如下:
$ gcc -g falldown.c -o falldown
$ ./falldown
Segmentation fault (core dumped)
$ gdb falldown.exe falldown.exe.core
3)在CYGWIN中对assert错进行分析.
在UNIX中,一旦在GDB中出现assert fail, 可以立即检查变量,分析程序调用过程。但是CYGWIN没有将此功能完整实现。绕过这个问题的一个方法是在这条assert语句所出现的位置的前一行设置断点 ,并以该语句条件的否定作为断点条件。假设该语句出现在文件 file1的第100行,那么设置 break file:99,断点语句为 a > 1. 那么设置条件:
break file1:99 if !(a>1)
4) 连接并考察一个正在运行的程序
假设程序A正在运行,它的进程号是12345。启动GDB,然后执行
(gdb) attach 12345
程序A被暂停,并且可以在GDB中观察。
5) 观察一个变量的读写过程
watch <变量> 可以显示该变量变化过程。对于一个局部定义的变量,需要进入到该函数中才能watch。
参考文献
[1] Debugging with GDB
http://sources.redhat.com/gdb/current/onlinedocs/gdb_toc.html
全面介绍GDB的手册
[2] The Complete Reference GCC
chapter 13: Using the GNU Debugger
GDB用法实例。
[3] GDB学习笔记1
GDB主要命令中文介绍
[4] gdb学习小结
GDB实现原理分析报告.
[5] Debugging in the Cygwin environment
关于在cygwin环境下使用GDB处理segmentation fault的方法.
[6] gdb on cygwin and debugging assert() or program segmentation faults
关于在cygwin环境下使用GDB处理assert的问题讨论.
[7] The Linux Development Platform - Table of Contents
http://www.faqs.org/docs/ldev/index.html
[8] How do I use gdb?
问题解答.
[9] Wiki: GNU Debugger
[10] Using GNU's GDB Debugger
By Peter Jay Salzman
[11] Guide to Faster, Less Frustrating Debugging
[12] Tips on Using GDB to Track Down and Stamp Out Software Bugs
GDB教学材料.