GDB - 暂停/恢复程序执行
在使用GDB调试程序的时候,经常需要暂停程序,以查看程序执行情况和上下文。GDB 提供了多种暂停程序的方式,包括 break point, watch point, catch point, signals 和 thread stop. 在此这些概念直接饮用,不作翻译。
1. 设置暂停点
# set breakpoint usage: break file:function # 在文件file 中 function函数入口处暂停 break *<addr> # 在addr地址位置暂停 break file:line # 在文件file 中 行line处暂停 break class::function # 在 c++ 中使用 break class::function(type,type,...) # 在 c++ 中使用 # breakpoint with condition usage:break ... if <condition> # 设置条件断点,'...'可以是上面任意类型,condition是条件表达式 -------------------------------------------------------------- # set watchpoints usage: wacth <expr> # 设置变更 watchpoint,即当表达式值发生变化时暂停 rwatch <expr> # 设置'读' watchpoint,即当有对表达式的读取访问时暂停 awatch <expr> # 设置 '读写' watchpoint, 无论读写都暂停,注写时表达式也不一定变化 ------------------------------------------------------------------- # set catchpoints usage:catch <event> # 设置捕捉点,捕捉运行时事件 tcatch <event> # 设置临时捕捉点 #event 可以是以下关键字 # throw - C++ 抛出异常事件 # catch - 捕捉到C++异常事件 # 这些功能很有用,有没有遇到过C++程序运行退出,但又没任何core文件产生,让你找不到原因的时候,试一下这个命令吧。(后面还会有一个有帮助的命令) |
2. 维护暂停点
在设置了breakpoints以后,有时候需要根据具体情况对之进行修改,删除等,或设置触发breakpoints以后的行为,以下是一些维护命令。
# list breakpoints usage: info breakpoints [n] # 查看所有的breakpoints信息, 查看breakpoint n info break [n] # 同上 -------------------------------------------------------------- # diable/enable breakpoints usage: disable breakpoints [m] [n] ... # 使一些 breakpoints 失效, 无参数则针对所有breakpoints enable breakpoints [m] [n] ... # 启用一些 breakpoints enable breakpoints once [m] ... # 启用,但在此处暂停后恢复到disable状态,即只enable这一次 enable breakpoints delete [m] ... # 启用,在此处暂停后删除该 breakpoint --------------------------------------------------------------- # delete breakpoints usage: clear #清除所有的breakpoints clear <function> #清除所有设置在函数function上的breakpoints clear <line> #清除所有设置在line行的breakpoints clear <file:function> clear <file:line> delete [breakpoints] [m] #删除m,不带break No. 则删除所有breakpoints --------------------------------------------------------- # condition breakpoints usage: condition <n> # 清除 breakpoint n 的条件 condition <n> <expr> # 修改 breakpoint n 的条件为 expr ignore <n> <count> # 忽略 breakpoint n 的停止条件 count 次,即前count次都把它作为无条件breakpoint对待 ------------------------------------------------------------- # set commands when pause at a breakpoint usage: commands <n> ...<command list>... end # 是 commands-end 对,由于给breakpoint n 设置暂停时执行的命令序列,如果命令为空,则清除在该breakpoint n 上的命令 |
3. 单步调试
在暂停程序以后,经常需要单步跟踪调试程序,单步调试命令如下。
usage: step [n] # 类似 VC中的 step-in, 即碰到函数会进入; n 表示步长,缺省为1; 这里的1步都是以程序语句为单位 next [n] # 类似 VC中的 step-over, 即碰到函数不进入,算作1步; n 表示步长,缺省为1 -------------------------------------------------- usage: stepi # 单步跟踪,1步代表一条机器指令,而不是程序语句 nexti # 单步跟踪,同上 ---------------------------------------------------- #set step mode usage: set step-mod on #打开步进模式开关,这样可以在不含调试信息的程序里进行单步跟踪 set step-mod off #关闭步进模式 ----------------------------------------------------------- usage: until # 运行到循环结束,当在循环体内跟踪想跳出循环时有用 --------------------------------------------------- #exit function usage: finish #执行到退出当前函数 |
4. 恢复执行/继续执行
在暂停程序以后,在已经达到目的,活着为达到下一步的调试目的,经常需要恢复暂停运行的程序,以下是恢复程序执行的命令。
usage: continue [ignore-count] # 恢复运行,并且忽略在运行过程中的 igore-count 次暂停(breakpoint 触发) usage: fg [ignore-count] # 同上 |
5. 处理信号
GDB提供在调试时处理任何一种信号的能力,关于信号的知识在此不作介绍。你可以要求GDB在收到信号时停止程序或采取其它动作,相关命令如下。
usage: handle <signal> <action> # 指示GDB在收到signal信号时采取action动作 #action 取值如下: # stop - 收到信号时停住被调试程序,打印信号名 # nostop - 收到信号时不停住被调试程序,仅打印信号名,提示收到信号 # print - 收到信号时,打印信号信息 # noprint - 收到信号时,不打印信号信息 # pass - 收到信号时交给被调试程序处理 # nopass - 收到信号时gdb不会让被调试程序处理该信号 ------------------------------------------------------- # list signals usage: info signals info handle #列出被gdb检测的信号 |
在你的程序无缘无故崩溃而又没有core文件时,通过处理 SIGTERM 信号定位问题,又是一种有效手段。
6. 针对多线程的breakpoints
如果你的程序是多线程的,那在设置breakpoints时需要考虑是否设置在所有的线程上,如果不是就需要指定线程,这样,就只有指定的线程会在运行到breakpoint位置暂停,相关命令如下。
# 前面设置breakpoints的方式在此仍然适用,只是需要指定 线程id, 如 usage: break <line> thread <thread-id> usage: break <line> thread <thread-id> if <condition> # 线程id是gdb分配的,可以通过如下方式获得 usage: info threads #list threads infomation |