gdb调试

1. 加断点

  • break <function>    在进入指定函数时停住
  • break <linenum>    在指定行号停住。
  • break +/-offset    在当前行号的前面或后面的offset行停住。offiset为自然数。
  • break filename:linenum    在源文件filename的linenum行处停住。
  • break classname::functionname
  • break filename:function  制定文件中的函数
  • break ... if <condition>    ...可以是上述的参数,condition表示条件,在条件成立时停住。比如在循环境体中,可以设置break if i=100,表示当i为100时停住程序。

2. 可以通过info breakpoints [n]命令查看当前断点信息。此外,还有如下几个配套的常用命令:

  • delete     删除所有断点
  • delete breakpoint n    d n删除某个断点
  • disable breakpoint n    disable n禁用某个断点
  • enable breakpoint n    enable n使能某个断点

3. 在特定线程中中断

你可以定义你的断点是否在所有的线程上,或是在某个特定的线程。GDB很容易帮你完成这一工作。

  • break <linespec> thread <threadno>
  • break <linespec> thread <threadno> if ...

linespec指定了断点设置在的源程序的行号。threadno指定了线程的ID,注意,这个ID是GDB分配的,你可以通过"info threads"命令来查看正在运行程序中的线程信息。如果你不指定thread <threadno>则表示你的断点设在所有线程上面。你还可以为某线程指定断点条件。如:

     (gdb) break frik.c:13 thread 28 if bartab > lim

当你的程序被GDB停住时,所有的运行线程都会被停住。这方便你你查看运行程序的总体情况。而在你恢复程序运行时,所有的线程也会被恢复运行。那怕是主进程在被单步调试时。

4. 恢复程序运行和单步调试

在gdb中,和调试步进相关的命令主要有如下几条:

  • continue    继续运行程序直到下一个断点(类似于VS里的F5)
  • next        逐过程步进,不会进入子函数(类似VS里的F10)
  • setp        逐语句步进,会进入子函数(类似VS里的F11)
  • until        运行至当前语句块结束
  • finish       运行至函数结束并跳出,并打印函数的返回值(类似VS的Shift+F11)
  • return      Make selected stack frame return to its caller
  • up            Select and print stack frame that called this one
  • down Select and print stack frame called by this one
  • frame       Select and print a stack frame
  • reverse-continue -- Continue program being debugged but run it in reverse
  • reverse-finish -- Execute backward until just before selected stack frame is called
  • reverse-next -- Step program backward
  • thread apply all -- Apply a command to all threads
  • thread apply -- Apply a command to a list of threads
  • info args -- Argument variables of current stack frame
  • info frame -- All about selected stack frame
  • info locals -- Local variables of current stack frame
  • info vector -- Print the status of the vector unit
  • info stack -- Backtrace of the stack
  • show backtrace -- Show backtrace specific variables
  • tsave -- Save the trace data to a file

PS:这些命令大部分可以简写为第一个字母,在日常使用过程中,往往只会输入第一个字符即可执行该命令,我标红的即是通常的使用方式。这几条命令使用非常频繁,并且可以带一些附加参数以实现高级功能,需要熟练掌握。


5.

layout:用于分割窗口,可以一边查看代码,一边测试。主要有以下几种用法:
layout src:显示源代码窗口
layout asm:显示汇编窗口
layout regs:显示源代码/汇编和寄存器窗口
layout split:显示源代码和汇编窗口
layout next:显示下一个layout
layout prev:显示上一个layout
Ctrl + L:刷新窗口
Ctrl + x,再按1:单窗口模式,显示一个窗口
Ctrl + x,再按2:双窗口模式,显示两个窗口

Ctrl + x,再按a:回到传统模式,即退出layout,回到执行layout之前的调试窗口。


6.生成core:

1)sudo gdb
2)shell gcore 24425
3) detach

7. 调试运行时进程:
1)通过–-pid参数来绑定指定的进程程序。
gdb --pid 25552
2)通过程序和进程号来绑定
gdb test 25552
3)先启动gdb后,通过attach来绑定pid
gdb
gdb) attach 25552

8. 指定源代码
1) gdb --pid 25552 -d ~/workspace/
2) directory ~/workspace/


9. 调试core file:
1) ar p bds-triton-sd_4.0.1.623-squeeze1_amd64.deb data.tar.gz | tar zxf -
2) schroot -c squeeze64
3) gdb ./usr/sbin/sd core.11077 --dir ../tms/t3/
4) thread apply all bt
5) t 2
6) f 2
调试子进程:set follow-fork-mode child
source ./.stl-views.gdb

5. 观察点(WatchPoint):

在变量读、写或变化时中断,这类方式常用来定位bug。

  • watch <expr>    变量发生变化时中断
  • rwatch <expr>    变量被读时中断
  • awatch <expr>     变量值被读或被写时中断

可以通过info watchpoints [n]命令查看当前观察点信息

6. 捕捉点(CatchPoint):

捕捉点用来补捉程序运行时的一些事件。如:载入共享库(动态链接库)、C++的异常等。通常也是用来定位bug。

捕捉点的命令格式是:catch <event>event可以是下面的内容

throw     C++抛出的异常时中断
catch     C++捕捉到的异常时中断
exec     调用系统调用exec时(只在某些操作系统下有用)
fork     调用系统调用fork时(只在某些操作系统下有用)
vfork     调用系统调用vfork时(只在某些操作系统下有用)
load 或 load <libname>     载入共享库时(只在某些操作系统下有用)
unload 或 unload <libname>     卸载共享库时(只在某些操作系统下有用)

backtrace(或bt)       查看各级函数调用及参数
finish   连续运行到当前函数返回为止,然后停下来等待命令
frame(或f) 帧编号 选择栈帧
info(或i) locals 查看当前栈帧局部变量的值
list(或l) 列出源代码,接着上次的位置往下列,每次列10行
list 行号 列出从第几行开始的源代码
list 函数名 列出某个函数的源代码
set var 修改变量的值
start 开始执行程序,停在main函数第一行语句前面等待命令
break ... if ... 设置条件断点
display 变量名 跟踪查看某个变量,每次停下来都显示它的值
info(或i)breakpoints 查看当前设置了哪些断点
run(或r) 从头开始连续运行程序
undisplay 跟踪显示号 取消跟踪显示
watch 设置观察点     
info(或i) watchpoints 查看当前设置了哪些观察点  
x 从某个位置开始打印存储单元的内容,全部当成字节来看,而不区分哪个字节属于哪个变量

设置打印全部字符:set print element 0

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章