惯用gdb调试技巧整理

常用gdb调试技巧整理
启动方法
1.gdb <program>
2.gdb <program> core
3.gdb <program> <PID>

=============================================================================================================
命令行参数
gdb命令行的 -args 参数
gdb环境中 set args 命令

=============================================================================================================
gdb中变量
可以查看运行时的变量,也可以直接设置程序中的变量,以模拟一些很难在测试中出现的情况,比较一些出错,或是switch的分支语句。使用set命令可以修改程序中的变量。
另外gdb也有变量,gdb的变量以$开头,比如打印数组中的每个元素,可以:
(gdb) set $i = 0
(gdb) p a[$i++]
.......然后一路回车下去了。


=============================================================================================================
常用命令
r                        ============>运行程序, run 命令简写
c                        ============>继续运行程序,continue命令缩写
l                        ============>列出源码, list 命令简写
b                        ============>设置断点,具体请看下面一节
info break               ============>查看断点信息
n                        ============>单条语句执行,不进入函数,next 命令缩写
s                        ============>单条语句执行,进入函数,step命令缩写
p i                      ============>打印变量值,print命令缩写
display i                ============>显示变量值,后面每行都会显示
bt                       ============>查看函数堆栈,backtrace命令缩写
finish                   ============>退出函数
q                        ============>退出gdb
直接回车                 ============>重复上一条命令
shell <command string>   ============>在gdb中运行shell脚本


===============================================================================================================
断点相关
break func                      ===============>在函数func入口处设置断点
break file.c:100                ===============>在file.c第100行设置断点
break [where] if [condition]    ===============>设置条件断点
break file.c:100 thread all     ===============>在file.c文件第100行处,为所有经过这里的线程设置断点
info break                      ===============>查看断点列表,会显示id号
delete id                       ===============>删除断点
clear func                      ===============>删除断点,不需要id,格式同break

info thread                     ===============>查看thread信息
t <thread id>                   ===============>切换到id进程,thread命令缩写



在gdb中,有几种暂停方式: 断点(breakpoint),观察点(watchpoint),捕捉点(catchpoint),信号(signals),线程停止(Thread Stops)
在gdb停住时,可以用info program来查看程序是否在运行,进程号,被暂停的原因。可以用continue来恢复程序运行

多线程调试
1.调试已运行的程序
     1)ps查看PID,然后gdb <program> PID挂接正在运行的程序
     2)gdb <program>关联上源代码,并进行gdb,在gdb中用attach命令来挂接进程的PID,用detach来取消挂接的进程。
2.
     info thread 查看当前进程的线程
     thread <id> 切换调试的线程为指定id的线程,t <id>
     break file.c:100 thread all     ===============>在file.c文件第100行处,为所有经过这里的线程设置断点
     set scheduler-locking off|on|step,在使用step或者continue命令调试当前被调试线程的时候,其他线程也是同时执行的,怎么只让被调试线程执行呢?通过这个命令就可以实现这个需求。
          off  不锁定任何线程,也就是所有线程都执行,这是默认值。
          on   只有当前被调试程序会执行。
          step 在单步的时候,除了next过一个函数的情况(熟悉情况的人可能知道,这其实是一个设置断点然后continue的行为)以外,只有当前线程会执行。

=================================================================================================================
调试宏
在gcc编译的时候,加上-ggdb3参数,就可以调试宏了。
info macro - 查看这个宏在那些文件被引用了,以及宏定义是什么样子的。
macro -      查看宏展开的样子

==================================================================================================================
自动化调试

使用command命令,简单的理解一下,其就是把一组gdb的命令打包,有点像字处理软件的“宏”。下面是一个示例:

(gdb) break func
Breakpoint 1 at 0x3475678: file test.c, line 12.
(gdb) command 1
Type commands for when breakpoint 1 is hit, one per line.
End with a line saying just "end".
>print arg1
>print arg2
>print arg3
>end
(gdb)
当我们的断点到达时,自动执行command中的三个命令,把func的三个参数值打出来。

========================================================================================================================
gdb server
这个主要是针对一些没有安装gdb的嵌入式设备
1)在目标target host上开启gdbserver
>>>>gdbserver <target host ip>:2345[这个端口可以自己根据需要设置] test
2)到host端,也就是安装有gdb的主机
>>>gdb test
[>>>set solib-absolute-prefix <gdb directory>]
[>>>set solib-search-path <gdb directory/lib或者其他库文件的路径>]
>>>target remote <target host ip>:2345

这时,就可以在host端来调试target上的程序了