The Art of Debugging with GDB

来源:互联网 发布:终极迈凯伦数据 编辑:程序博客网 时间:2024/05/15 08:08

CH1

1. Ctrl +P,Ctrl+N可以浏览以前的命令并编辑,回车键则是重复上一次的命令;

2.版本6.1以后,有TERMINAL USER INTERFACE模式提供了基于图形界面和文本界面的折中;

为了以TUI模式运行gdb,需要指定-tui选项;或者在调试时输入CTRL+X+A组合键;

3.在run后可以为程序添加参数;

例如 r  6 5, 运行程序并传了两个字符串参数(需要把6和5用atoi转为int)

4.在普通模式下,上下键用于浏览以前的命令历史;

在TUI模式下,则是用于滚动源代码子窗口;此时请用CTRL+P CTRL+N查看历史命令

5.临时断点的设置:tbreak命令;类似于捕鼠器模式,一次命中即失效;

6.watch一个变量,每当他的值变化时,就会暂停运行;可以有rwatch,每次读取时都暂停;

watch a>10 则是,当a首次大于10时,暂停执行

7.当前正在运行的函数frame编号为0;gdb的up和down命令会切换frame;backtrace显示整个栈

 

8.condition [断点号] [停止在该断点处的条件]
condition 1 i==239(假如断点号为1)

用break和if可以组合两个命令

break [行号] if [条件]

 

CH2 stop and watch your program
1.暂停机制有以下三种:
设置断点;
监视点:当特定内存位置的值发生变化或被读取时暂停执行;
捕获点:当特定事件发生时暂停

delete可以删除这三种断点,如果不加参数,就是清空所有断点;

break *address 这种用法可以用来在虚拟内存地址处设置断点,这对于程序没有调试信息的部分(比如源代码不可用,或者是共享库)是必须的

捕获点:用catch来设置,能够被抛出、捕获异常、发信号、调用fork、加载、卸载库以及很多事件触发;
 
2 断点的属性:
用info b输出属性。
类型Type:指出是断点、监视点还是捕获点;
Disp(osition):指示断点下次生效时,会发生什么事情;有以下三种:
keep:断点继续存在;
del:断点被删除,这是tbreak设置的断点;
dis:被禁用;这是enable once 设置的断点
 
3.断点后恢复执行。
next和step、continue就不说了
注意continue可以加个数字参数,意思是忽略多少个断点;
 
finish:恢复执行,到当前栈帧完成为止;
until:不进一步在循环中暂停的情况下完成当前循环 
4.让GDB在每次到达某断点时自动执行一组命令:
使用commands命令,格式如下
commands break-number
。。。
your command
。。
end
 
使用silent使GDB安静的触发断点,避免冗余输出
如果命令列表中最后一个命令是continue,gdb将会自动继续执行程序;
 
5.监视点
硬件监视点:
数量是有限的。如果不可用,会输出:
Stopped; cannot insert breakpoints;
You may have requested too many hardware breakpoints and watchpoints;

 

CH3 检查和设置变量
 
display命令:每次暂停时,就输出指定条目;
也可以用commands命令

GDB的call命令:
可以调用源代码中的函数;

2.检查数组
普通数组只需要print 数组名即可;
若是动态数组 int * arr = new int[10];
print
*arr@10
也可以强制类型转化:
print (int [10]) *arr
 
3. ptype可以查看结构类型
 
4.info locals可以查看当前栈的局部变量。
 
5.直接检查内存
x命令
 
6.print 和display的选项:
print /x a 以16进制显示a
其它格式:c表示char,s表示string,f表示float
删除:undisplay
 
7.值历史
GDB的print命令的输出值被标示为$1 $2.这些值统称为值历史;
可以这样输出 print $1
 
8.方便变量
情形:有一个指针p,在不同的时候指向链表中的不同节点;
你可能希望监视其中某个节点的值的所有变化;
当p首次指向这个节点时,你可以用方便变量:
set $cur = p
$cur就是方便变量
打印它就是了。

 

 

CH4 程序崩溃处理
 
1.为什么数组越界访问不会立即出错?
假如:机器上的虚拟页大小为4KB。
声明了一个int a[200];它不足以占据一页;
假如它所在的页有剩余空间,那么越界访问只要不超过本页,是不会出错的。

2.发送信号给进程的含义:
OS将信号记录到相应的进程表中,随后执行信号处理程序;

3.CORE FILE
ulimit -c n 控制core文件大小不超过nKB
要调试core文件,这个n设置足够大,否则无法正确core dump
gdb exefile corefile 来调试corefile,它是因为可执行文件exefile执行失败而产生的。

 

补充:
在编辑器中设置 set list以显示制表符^I
还有ltrace、mtrace等工具。。

 

 

多线程调试的一项技巧:

命令 : set scheduler-locking off|on|step

在使用step或者continue命令调试当前被调试线程的时候,其他线程也是同时执行的,怎么只让被调试程序执行呢?通过这个命令就可以实现这个需求。
off 不锁定任何线程,也就是所有线程都执行,这是默认值。
on 只有当前被调试程序会执行。
step 在单步的时候,除了next过一个函数的情况(熟悉情况的人可能知道,这其实是一个设置断点然后continue的行为)以外,只有当前线程会执行。

原创粉丝点击