使用gdb调试多线程多进程程序
来源:互联网 发布:金元证券软件下载 编辑:程序博客网 时间:2024/05/18 18:21
GDB的基本介绍
GDB是GUN开源组织发布的一个强大的UNIX下的程序调试工具。或许,平时大家更加习惯图形界面的调试,比如VS上的IDE调试;但是如果我们在UNIX或Linux下做软件,我们呢就更加需要熟练GDB这个调试工具。
一般来说,GDB主要能够完成以下的几个功能:
①启动你的程序,可以按照你自己的要求随性所欲的运行程序;
②可以让被调试的程序在你自己所定的位置的断点处挺住;
③当程序被停住时,可以检查此时你的程序中所发生的事情;
④动态的改变你程序的执行环境。
GDB调试使用的是DEBUG版本的,所以我们在生产可执行文件时,我们需要在命令的尾部加上 -g,这样就可以生成的是DEBUG版本下的可执行文件。
调试代码的基本命令
命令作用list或l + 行号显示从行号开始的源代码list或l + 函数名列出某个函数的源代码run或r 运行程序step或s进入函数调用breaktrace或bt查看各级函数调用及参数info或ilocals查看当前栈帧局部变量的值info break查看断点信息finish执行到当前函数返回,然后停下来等待命令print或p打印表达式的值,通过表达式可以修改变量的值或者调用函数break或b + 行号在某一行设置断点set var修改变量的值quit退出调试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 + 变量打印变量值list或l列出源代码,接着上次的位置往下列,每次列10行frame或f帧编号,选择栈帧start开始执行程序,停在main函数第一行语句前面等待命令call + 函数名强制调用某个函数GDB调试多进程
在默认情况下是调试多进程程序时GDB会默认调试主进程,但是GDB支持多进程的分别与同步调试。即GDB支持同时调试多个进程,只需要设置follow-fork-mode(默认为parent)和detach-on-fork(默认为on)即可。我们还可以使用catch fork指令,如果fork异常,会停止程序。follow-fork-modedetach-on-fork说明parenton只调试主进程(GDB默认)childon只调试子进程parentoff同时调试两个进程,gdb跟主进程,子进程block(阻塞)在fork位置childoff同时调试两个进程,gdb跟子进程,主进程block在fork位置设置方法: set follow-fork-mode[parent|child] set detach-on-fork[on|off]
显示:show follow-fork-mode show detach-on-fork
下面通过代码来演示
调试步骤:
只调试父进程
只调试子进程(与上面的对比起来看)
下面呢我们开始直接调试两个进程(父进程运行调试,子进程阻塞等待)
最后我们进行子进程运行调试,父进程阻塞等待
GDB调试多线程
在多线程编程时,当我们需要调试时,有时需要控制某些线程停在断点处,有些线程继续执行;有时需要控制线程的运行程序;有时需要中断某个线程,切换到其他线程。这些呢都可以通过gdb来实现。GDB默认支持调试多线程,跟主线程,子线程block在create+thread。
gdb调试一般有两种模式:all-stop模式和no-stop模式(gdb7.0之前不支持no-stop模式)。
1.all-stop模式
在这种模式下,当你的程序在gdb由于任何原因而停止,所有的线程都会停止,而不仅仅是当前的线程。一般来说,gdb不能单步所有的线程。因为线程调度是gdb无法控制的。无论什么时候当gdb停止你的程序,它都会自动切换到触发断点的那个线程。
2.no-stop模式(网络编程常用)
顾名思义,启动不关模式。当程序在gdb中停止,只有当前的线程会被停止,而其他线程将会继续运行。这时候step,next这些命令就只对当前线程起作用。
如果需要打开no-stop模式,可以向~/.gdbinit添加配置文件:
gdb支持的命里有两种类型:前台的(同步的)和后台(异步 )的。区别很简单,同步的在输出提示符之前会等待程序report一些线程已经终止的信息,异步则是直接返回。所以我们需要set target-async 1。set pagination off不要出现 Type <return> to continue 的提示信息 。最后一步是打开。
下面看一下gdb调试多线程常用命令:
命令作用info threads显示所有可调试的线程thread ID切换到指定线程,gdb为每一个线程分配一个ID(与tid不同),编号一般从1开始breakfilename:linenum thread all在所有线程相应行设置断点,注意如果主线程不会执行到该行,并且启动all-stop模式,主线程执行n或s会切换过去set scheduler-locking off|on\step默认off,执行s或c其它线程也同步执行。on,只有当前相称执行。step,只有当前线程执行show scheduler-locking显示当前模式thread apply all command每个线程执行同意命令,如bt。或者thread apply 1 3 bt,即线程1,3执行bt。通过代码来演示:
调试步骤:
开始调试:
然后开始运行代码:
单步调试:
切换到其他线程:
再切换到其他线程调试:
设置core文件
core的意思是核心,dumped的意思就是抛出,转储,core dumped就是核心转储的意思。当一个进程异常退出前,该进程会抛出当时该程序进程的内存详细情况存储在硬盘上,文件名通常是core,这就叫core dump。
进程异常终止通常是因为代码存在BUG,比如非法内存访问导致段错误,事后可以用调试器检查core文件以查清错误原因,这叫做事后调试。
uname -a 查看机器参数
ulimit -a 查看默认参数
ulimit -c 1024 设置core文件大小为1024
ulimit -c unlimit 设置core文件大小为无限
ulimit -c unlimited 生成core文件,也可以是指定大小,然后使用gdb ./main core启动,bt查看调用栈即可。
eg1(可以快速定位出问题的位置)
gdb a.out core.xxx
where
eg2 (在 gdb 中使用)
(gdb) core-file core.xxx
- 使用gdb调试多进程多线程程序
- 使用gdb调试多进程多线程程序
- 使用gdb调试多进程多线程程序
- 使用gdb调试多进程多线程程序
- 使用GDB调试多进程/多线程程序
- 使用gdb调试多进程多线程程序
- 使用gdb调试多进程、多线程程序
- 使用gdb调试多线程多进程程序
- 使用gdb调试多进程及多线程程序
- 使用gdb调试多进程和多线程程序
- Linux下使用gdb调试多进程与多线程程序
- 【Linux】使用gdb调试多进程多线程程序
- Linux----使用GDB调试多进程和多线程程序
- 使用gdb调试多进程与多线程程序
- Linux:如何使用gdb调试多进程多线程程序
- 使用gdb调试多进程多线程调试
- gdb调试多进程和多线程程序
- gdb调试多线程多进程程序
- 技术面总结
- gamemaker学习笔记:推箱子
- LSPCI命令打印出PCI总线上连接的所有设备
- 现在谈谈Vue 里面的computed 属性
- javascript数据结构系列(四)-队列
- 使用gdb调试多线程多进程程序
- AtomicInteger 类的理解与使用
- HDU6165 FFF at Valentine(并查集+tarjan缩点+拓扑排序)
- msyql 查看行锁情状况
- 【Spark2.0源码学习】-3.Endpoint模型介绍
- 这么多开源框架,该用哪个好?
- 组合模式
- Linux基本操作命令
- 【MVP】AppManager一些有关Activity和程序退出的操作