今天把所有的GDB常用的调试命令都过了一遍,尤其是多线程调试。所以先做个总结,以免忘记。以后如果有新的有用的命令会继续追加。
本文地址:(LYanger的博客:
http://blog.csdn.net/freeelinux/article/details/53700266
)
一:普通命令
1.list命令
-
list linenum 显示程序第linenum行周围的程序
-
list function 显示函数名为function的函数的源程序
-
list 显示当前行后面的源程序
-
list - 显示当前行前面的源程序
2.run(r)
运行命令。
-
run args
run命令可以直接接命令行参数值,也可以在执行run之前通过 set args + 参数值实现。
3.break(b)
打断点,使用方法:
-
b linenum 在某行打断点
-
b +offset/-offset 在当前行号的前面或后面offset停住
-
b filename:linenum 在某文件的某行打断点
-
b filename:function 在某文件某个函数入口停住
-
b *address 在程序的运行地址处停住
-
b 没有参数在下一句停住
-
b where if condition 当某个条件满足时,在某一行停住
(这个很有用,比如b 10 if ret == 5)
对于break命令,我们要灵活使用。例如打多个断点。多线程程序中我们可以主函数中线程创建后立即打断点,执行线程函数入口打断点等。
关闭断点:delete(d) breakpoint-id
-
step count 一次性执行count步,如果有函数会进入函数
-
next count 一次执行count,不进入函数
-
finish 运行程序,直到当前函数完成返回,并打印函数返回时的堆栈地址和返回值以及参数信息
-
until 退出循环体
(尤其是针对for循环这种,很烦的)
5.continue命令
当程序被停住之后,可以使用continue(c)命令,恢复程序的运行直到程序结束,或到达下一个断点。
这里要注意如果没有断点程序是会直接结束的。
-
x 按十六进制格式显示变量
-
d 按十进制格式显示变量
-
u 按十六进制格式显示无符号整型
-
o 按八进制格式显示变量
-
t 按二进制格式显示变量t 按二进制格式显示变量
-
a 按十六进制格式显示变量
-
c 按字符格式显示变量
-
f 按浮点数格式显示变量
7.watch命令
这个命令比较有用。watch一般用来观察某个表达式(变量也是一种表达式)的值是否有变化,如果有变化,马上停住程序。我们有一下几种方法设置观察点:
-
watch expr 为表达式expr设置一个观察点,一旦表达式值有变化,马上停住程序
-
rwatch expr 当表达式expr被读时,停住程序
-
awatch expr 当表达式的值被读或被写时,停住程序。
-
info watchpoints 列出所有观察点(info指令通常可以去套)
举例如下,演示观测*i的值,一旦变化停下来:
addr表示一个内存地址。“x/”后的n、f、u都是可选的参数,n 是一个正整数,表示显示内存的长度,也就是说从当前地址向后显示几个地址的内容;f 表示显示的格式,如果地址所指的是字符串,那么格式可以是s,如果地址是指令地址,那么格式可以是i;u 表示从当前地址往后请求的字节数,如果不指定的话,GDB默认是4字节。u参数可以被一些字符代替:b表示单字节,h表示双字节,w表示四字节,g表示八字节。当我们指定了字节长度后,GDB会从指定的内存地址开始,读写指定字节,并把其当作一个值取出来。n、f、u这3个参数可以一起使用,例如命令“x/3uh 0x54320”表示从内存地址0x54320开始以双字节为1个单位(h)、16进制方式(u)显示3个单位(3)的内存。
-
jump linespec 指定下一条语句的运行点,linespec可以是linenum,filename+linenum,+offset这几种形式
-
jump address 跳到代码行的地址
10.signal命令
使用signal 信号名(如SIGINT)这种方式把信号发送给程序,如果程序注册了signal_handler函数,还可以进行相应的处理,帮助调试程序。
11.set命令
-
set args 设置命令行参数
-
set env environmentVarname=value 设置环境变量。如:set env USER=benben
12.call命令
强制调用某函数,它会显示函数返回值(如果函数返回值不是void)。print命令也可以完成该功能。
1.单独调试子进程
我们可以先运行程序,然后再另一终端使用ps -ef | grep "main"(main此处是可执行文件名)搜索到子进程pid,然后启动gdb,在将其附加(attach)到gdb调试器上。
-
attach child-pid
使用该命令后,直接run即可,和调试普通程序就没区别了
-
dettach 脱离进程
2.使用调试器选项follow-fork-mode
我们知道如果不设置任何选项,gdb默认调试父进程。调试器选项用法如下:
-
set follow-fork-mode mode
其中mode的可选值是parent和child,分别表示调试父进程和子进程。
-
info inferiors 查询正在调试的进程
-
inferior processnum 切换进程
默认设置下,在调试多进程程序时GDB只会调试主进程。但是GDB(>V7.0)支持多进程的分别以及同时调试,换句话说,GDB可以同时调试多个程序。只需要设置follow-fork-mode(默认值:parent)和detach-on-fork(默认值:on)即可。我们还可以使用catch fork指令,如果fork异常,会停止程序。
follow-fork-mode detach-on-fork
说明
parent on 只调试主进程(GDB默认)
child on 只调试子进程
parent off 同时调试两个进程,gdb跟主进程,子进程block在fork位置
child off 同时调试两个进程,gdb跟子进程,主进程block在fork位置
设置方法:set follow-fork-mode [parent|child] set detach-on-fork [on|off]
在这种模式下,
当你的程序在gdb由于任何原因而停止,所有的线程都会停止
,而不仅仅是当前的线程。一般来说,gdb不能单步所有的线程。因为线程调度是gdb无法控制的。
无论什么时候当gdb停止你的程序,它都会自动切换到触发断点的那个线程
2.no-stop模式(网络编程常用)
顾名思义,启动不关模式。当程序在gdb中停止,
只有当前的线程会被停止,而其他线程将会继续运行
。这时候step,next这些命令就只对当前线程起作用。
如果需要打开no-stop模式,可以向~/.gdbinit添加配置文件:
#Enable the async interface
set target-async 1
#If using the CLI, pagination breaks non-stop
set pagination off
#Finall, turn it on
set non-stop on
gdb支持的命里有两种类型:前台的(同步的)和后台(异步 )的。区别很简单,同步的在输出提示符之前会等待程序report一些线程已经终止的信息,异步则是直接返回。所以我们需要set target-async 1。set pagination off不要出现 Type <return> to continue 的提示信息 。最后一步是打开。
下面是常用命令:
-
info threads 显示所有线程
-
thread id 切换到指定线程
-
break filename: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。
主要是我们要用能用的上的,比如no-stop模式,一般多线程调试就很有用的。
四:core文件
-
ulimit -c unlimited 生成core文件,也可以是指定大小,然后使用gdb ./main core启动,bt查看调用栈即可。
今天把所有的GDB常用的调试命令都过了一遍,尤其是多线程调试。所以先做个总结,以免忘记。以后如果有新的有用的命令会继续追加。一:普通命令1.list命令list linenum 显示程序第linenum行周围的程序list function 显示函数名为function的函数的源程序list 显示当前行后
当在linux下运行的代码中有创建子进程的操作时,当进行
gdb调试
时会默认选择父进程进行
调试
,假如需要对子进程进行
调试
就需要使用特殊方法。共有两种方法可供选择:这个方式就是当进程运行时,获取进程PID然后在进入
gdb调试
时,通过attach指令
调试
PID对用的进程。本质就是指定PID然后
调试
,并不是真正的进程切换
调试
。示例代码:
过程如下: mode的可供选择值有两个parent与child,对应父进程与子进程。
这个只能选择fork的第一个子进程作为child进行
调试
。还是使用上述示例代码,过程如
众所周知,
gdb
调式是一门很深的学问,最近在
多线程
调式的时候遇到一些问题,今天就此记录下来。开始的时候参考了网上很多的
多线程
调式
技巧
以及基本
命令
,所以基本的
命令
和方法我只会简略地记录。
1.
gdb
多线程
基本
命令
首先设置non-stop模式,非常重要,因为
多线程
模式下面,如果不设置此模式,例如你程序有等待其他线程的工作为前提的代码,那么你的程序就得不到正确的运行。举个例子,比如你有一个子线程...
GDB
(GNU Debugger)是类 Unix(如 Linux)操作系统下的一款开源的 C/C++ 程序
调试
器。
对于大多数由内存访问冲突导致的程序崩溃,我们都可以使用
GDB
分析产生的core 文件来定位问题原因;另外对于一些出现几率比较低,比如一万次操作可能只会出现一个,我们可以在不修改程序代码的前提下,使用
GDB
条件断点的功能设置触发条件,最终定位和解决问题。
Linux 下 C++ 程序开发,即使使用 makefile、cmake 等编译工具,其最终都是调用 gcc 这一编译工具组的。.
/ #
gdb
server --multi localhost:1234
Listening on port 1234
Remote debugging from host 10.213.0.8
Attached; pid = 379 <<<<<<<<
gdb
client connect
在linux下程序崩溃时,一般会在指定目录下生成一个core文件。core文件仅仅是一个内存映象(同时加上
调试
信息),主要是用来
调试
的,接下来我们通过一个案例观察怎么利用
GDB调试
core文件。在
命令
行中键入
gdb
<可执行文件> < core文件>:
进入
gdb
命令
行中:
键入 bt 可以查看程序终止线程的堆栈:
但是有时错误不是发生在这个堆栈上。键入 info threads 查看所
一、
gdb调试
多进程
多线程
代码
2.默认设置下,在
调试
多进程
程序时
GDB
只会
调试
主进程。但是
GDB
(>V7.0)支持
多进程
的分别以及同时
调试
,换句话说,
GDB
可以同时
调试
多个程序。只需要设置follow-fork-mode(默认值:parent)和detach-on-fork(默认值:on)即可。 follow-fork-mode 和detach-on-fork 说明
<1>,设置方法:
c 当程序在某一断点处停下后,用该
命令
可以继续执行,直到遇到断点或者程序结束
n 代码一行一行的执行
s 如果有调用函数,就进入函数的内部,否则就一行一行的执行
u 在一个循环体内,可以运行程序直到退出循环体
p 打印指定变量的值,
l 显示源代码程
gdb
与
多线程
在
多线程
编程时,当我们需要
调试
时,有时需要控制某些线程停在断点,有些线程继续执行。有时需要控制线程的运行顺序。有时需要中断某个线程,切换到其他线程。这些都可以通过
gdb
实现。
先看一下
gdb调试
多线程
常用命令
: