当前位置:文档之家› GDB调试简易教程

GDB调试简易教程


设置断点(break point)
`break ... if COND` 条件断点,当表达式COND非零时程序在断 点停止 例如`break 253 if i=10` `tbreak …` 设置一个只会停止一次的断点
设置观察点(watch point)
`watch EXPR` 为EXPR设置一个观察点,一旦EXPR被写入并发生变化,程 序停止 `rwatch EXPR` EXPR被读取时,程序停止 `awatch EXPR` EXPR被读取或者被写入时,程序停止 当程序运行到EXPR作用域以外的地方时,GDB将会自动删 除此观察点,如果想继续观察,必须重新设置观察点。
启动:
最通常的命令就是使用一个参数: $(m68k-linux-)gdb <可执行文档名> 你还可以同时为你的执行文件指定一个core文件: $gdb <可执行文件名> core 你也可以为你要执行的文件指定一个进程号:
$gdb <可执行文件名> <进程号>
常用启动参数:
-symbols <文件名>(-s <文件名>) 从<文件名>中读去符号 -x <文件名> 执行gdb命令,在<文件名>指定的文件中存放着一序列的gdb 命令,就象一个批处理 -directory(-d) <路径> 指定路径。把<路径>加入到搜索源文件的路径中
程序的恢复与单步调试

finish 运行程序,直到当前函数完成并返回,打印函数返回时的堆 栈地址和返回值及参数值等信息 until [location] 简写为u,继续运行程序直至跳出当前正在单步调试的循环体; 加参数表示继续运行到代码的location处或者当前stack frame返回


advance location 继续运行直至location处
GDB下运行程序
调试子进程的技巧:
正常情况下,可以在子进程运行后attach即可 如果需要调试子进程在启动过程中的问题,可以采取以下方法:

父进程启动代码: pid = fork(); if (0 == pid) exec(―sh‖ ―–c‖ ―child‖); 更改为 pid = fork(); if (0 == pid) exec(―sh‖ ―–c‖ ―gdb child‖);
查看程序堆栈
backtrace 可以简写为bt,打印当前的函数调用栈的所有信息 frame [n] 可以简写为f,切换到堆栈的第n层 up/down 在堆栈中向上/向下移动 info frame 打印更加详细的当前栈层的信息 info args 打印出当前函数的参数名及其值 info locals 打印出当前函数中所有局部变量及其值
GDB下运行程序
Run命令:
用于启动你的程序,使用命令前必须先指定你程序的名字(用 gdb的命令行参数)或使用‘file‘命令,来指定文件名
工作路径:
每次用‘run‘命令来运行程序时,程序将继承gdb的当前工作目 录。而gdb的工作目录是从它的父进程继承而来的(一般是shell)。 但你可以自己使用‘cd‘命令指定工作目录。 gdb的工作目录就是它去寻找某些文件或信息的途径。 `cd DIRECTORY' 把gdb的工作目录设为DIRECTORY `pwd' 打印输出当前目录
断点相关操作
为断点设置条件 condition bNum EXPR 为该断点设置条件 condition bNum 取消该断点的条件

忽略断点 ignore bnum count

忽略该断点count次
为断点设置命令列表
commands [bnum] ... command-list ... end 断点被触发后可以执行指定的命令列表

命令输入技巧:
可以把一个gdb命令缩写成开头几个字母,如果这没有二意性你可以直接回车来运行。 如果有不止一个选择的话,你还可以使用TAB键让gdb给你完成接下来的键入,或向你 显示可选择的命令

使用help
Hale Waihona Puke help [class] 显示某一类命令的列表
status Status inquiries.
处理信号


info signals/handle 打印各种已经定义处理方法的信号列表 handle signal keywords... 定义各种信号的处理方法 keywords: nostop 当被调试的程序收到信号时,GDB不会停止程序的运行, 但会打印信息通知用户收到这种信号 stop 当被调试的程序收到信号时,GDB会停止程序的运行 print/noprint 当被调试的程序收到信号时,GDB 会/不会 打印 出一条信息 pass GDB不会拦截信号,留给应用程序处理 nopass GDB拦截信号,不会让应用程序去处理
常用启动参数:
-quiet (-q) 安静模式,不输出介绍和版权信息 -x <文件名> 执行gdb命令,在<文件名>指定的文件中存放着一序列的gdb 命令,就象一个批处理 -directory(-d) <路径> 指定路径。把<路径>加入到搜索源文件的路径中
结束:
quit 直接退出gdb detach 放弃连接

子进程的main函数中使用sleep进行延时,睡眠期间attach之
断点



断点的作用是当你程序运行到断点时,无 论它在做什么都会被停止下来 可以在行上,函数上,甚至在确切的地址 上设置断点 观察点是一种特殊的断点。它们在程序中 某个表达式的值发生变化时起作用 可以设置当程序被中断时显示的程序变量
断点相关操作

查看断点
info breakpoints info watchpoints info break [n]

删除断点 禁止、使能断点
clear delete disable [breakpoints] 不带参数则禁止所有断点 enabe [breakpoints] 不带参数则使能所有断点 enable [breakpoints] once 使能,并在程序停止后禁止 enable [breakpoints] delete 使能,并在程序停止后删除
GDB下运行程序
程序编译:
当你在gdb下运行程序时,你必须先为gdb准备好 带有调试信息的可执行文档。 为了高效的调试一个程序,你需要使用编译器来产 生附带调试信息的可执行代码这些调试信息存储在 目标文件中;描述了变量数据类型和函数声明,在 源文件代码行和执行代码之间建立联系。 为产生调试信息,当你使用编译器时指定'-g'选项, 就可以为你的程序产生带有调试信息的可执行代码
Shell命令:
shell <command string> 启动一个shell执行<command string>, 不用退出GDB就可以执行一个shell命令 make [make-args] 使用[make-args]进行make 相当于`shell make make-args'
GDB命令
设置断点(break point)
使用‘break‘或简写成‘b‘来设置断点: `break function` 在某个函数上设置断点 `break + offset` `break – offset` 当前行的前(后)offset行上设置断点 `break filename:linenum` 在文件的某行设置断点 `break filename:function` 在文件的某函数设置断点 `break *address` 在地址address上设置断点,可以在无调试信息的程序中设置断点
GDB下运行程序
调试一个多线程的程序:
GDB会自动提示新线程创建 thread <threadno> 各线程间进行切换 info threads 查看已经存在的线程 无论gdb何时中断了你的程序(因为一个断点或是 一个信号),它自动选择信号或断点发生的线程 为当前线程。gdb将用一个格式为'[Switching to SYSTAG]'的消息来向你报告。
程序的恢复与单步调试




continue 简写为c,恢复程序运行,直到下一个断点或程序结束 step 简写为s,单步调试,如果有函数调用,会进入该函数。进入 函数的前提是,此函数被编译有调试信息 next 简写为n,单步调试,如果有函数调用,不会进入该函数 set step-mode `set step-mode on` 打开step-mode模式,在进行单步 调试时,不会因程序没有编译入调试信息而忽略“Step in‖ 。 这个参数有很利于查看程序运行时的汇编代码 `set step-mode off` 关闭step-mode模式
GDB下运行程序
调试多进程:
GDB对调试使用'fork'系统调用产生新进 程的程序没有很多支持。当一个程序开始 一个新进程时,GDB将继续对父进程进行 调试,子进程将不受影响的运行。如果你 在子进程可能会执行到的地方设了断点, 那么子进程将收到'SIGTRAP'信号,如果 子进程没 有对这个信号进行处理的话那么 缺省的处理就是使子进程终止。
查看运行时的数据
最常用的查看数据方法 print /FMT EXPR 按照格式FMT打印表达式EXPR的值
display /FMT EXPR 自动按照格式FMT打印表达式EXPR的值
例如: print /x i 以十六进制格式打印i的值
查看运行时的数据
表达式:
print和许多GDB的命令一样,可以接受一个表达 式,GDB会根据当前的程序运行的数据来计算这个 表达式,既然是表达式,那么就可以是当前程序运 行中的const常量、变量、函数等内容。但是GDB 不能使用调试程序中所定义的宏
相关主题