Chinaunix首页 | 论坛 | 博客
  • 博客访问: 52201
  • 博文数量: 12
  • 博客积分: 266
  • 博客等级: 二等列兵
  • 技术积分: 100
  • 用 户 组: 普通用户
  • 注册时间: 2011-10-26 16:10
文章分类
文章存档

2012年(7)

2011年(5)

分类: LINUX

2011-11-11 15:21:51

一。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教学材料.

阅读(1934) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~