Linux下使用gdb调试多进程与多线程程序
常见gdb基本指令
在Linux环境下,我们使用gdb对代码进行调试。下面先来看看常用的gdb调试指令:
- list/l ⾏号 —> 显⽰binFile源代码,接着上次的位置往下列,每次列10⾏。
- list/l 函数名 —> 列出某个函数的源代码。
- r/run —> 运⾏程序。
- s或step —> 进⼊函数调⽤
- breaktrace(或bt) —> 查看各级函数调⽤及参数
- info( i) locals —> 查看当前栈帧局部变量的值
- info break —> 查看断点信息。
- finish —> 执⾏到当前函数返回,然后挺下来等待命令
- print(p) —> 打印表达式的值,通过表达式可以修改变量的值或者调⽤函数
- set var —> 修改变量的值
- quit —> 退出gdb
- break(b) ⾏号 —> 在某⼀⾏设置断点
- break 函数名 —> 在某个函数开头设置断点
- continue(或c) —> 从当前位置开始连续⽽⾮单步执⾏程序
- run(或r) —> 从开始连续⽽⾮单步执⾏程序
- delete breakpoints —> 删除所有断点
- delete breakpoints n —> 删除序号为n的断点
- disable breakpoints —> 禁⽤断点
- enable breakpoints —> 启⽤断点
- info(或i) breakpoints —> 参看当前设置了哪些断点
- display 变量名 —> 跟踪查看⼀个变量,每次停下来都显⽰它的值
- undisplay —> 取消对先前设置的那些变量的跟踪
- until X⾏号 —> 跳⾄X⾏
- n 或 next —> 单条执⾏。
- p 变量 —> 打印变量值。
gdb与多进程
先来看代码吧
调用fork函数创建一个子进程
一般默认情况下,调试多进程程序时gdb只会调试主进程。但是gdb(>V7.0)支持多进程的分别以及同时调试,换句话说,gdb可以同时调试多个进程。
要实现该功能,只需要对follow-fork-mode和detach-on-fork进行设置即可。
一般follow-fork-mode默认值为parent, detach-on-fork默认值为on(即默认只调试主进程)
下面对follow-fork-mode和detach-on-fork简单介绍一下
设置方法:
* set follow-fork-mode [parent|child] set detach-on-fork [on|off]显示方法:
* show follow-fork-mode ;
* show detach-on-fork;
具体操作看下图:
由此,父子进程同时调试,gdb跟进子进程,父进程阻塞在fork位置。
查看正在调试的进程
* info inferiors
切换正在调试的进程号为number
* inferior number
gdb会为当前正在调试的进程序列分配id
详情看图:
add-inferior [-copies n] [-exec executable] ,可以用file executable来分配给inferior可执行文件。
添加新的调试进程。增加n个inferior并执行程序为executable。如果不指定n只增加一个inferior。如果不指定executable,则执行程序留空,增加后可使用file命令重新指定执行程序。这时候创建的inferior其关联的进程并没启动。remove-inferiors number
删除一个number号的inferior。如果inferior正在运行,则不能删除,所以删除前需要先kill或者detach这个inferior。detach inferior number
detach掉编号是number的inferior。注意这个inferior还存在,可以再次用run命令执行它kill inferior number
kill掉number号inferior。注意这个inferior仍然存在,可以再次用run等命令执行它。
gdb与多线程
同样,来看代码吧!
gdb默认支持调试多线程,跟主线程,子线程block在create thread。
来看一下常用的线程调试指令吧
查看线程
* info threads
切换调试线程number
* thread number
- break FileName.cpp:LinuNum thread all—>所有线程都在文件FileName.cpp的第LineNum行有断点。
- thread apply ID1 ID2 IDN command—>多个线程执行gdb命令command。
- thread apply all command—>所有线程都执行command命令。
- set scheduler-locking off|on|step—>在调式某一个线程时,其他线程是否执行。off,不锁定任何线程,默认值。on,锁定其他线程,只有当前线程执行。step,在step(单步)时,只有被调试线程运行。
- set non-stop on/off—>当调式一个线程时,其他线程是否运行。
- set pagination on/off—>在使用backtrace时,在分页时是否停止。
- set target-async on/ff—>同步和异步。同步,gdb在输出提示符之前等待程序报告一些线程已经终止的信息。而异步的则是直接返回。