GDB常用命令使用

GDB(GNU Debugger)是在Unix以及类Unix系统下的调试工具。功能极其强大,几乎涵盖了你所需要的全部功能。 
GDB主要帮忙你完成下面四个方面的功能: 
1.启动你的程序,可以按照你的定制要求随心所欲的运行程序。 
2.可让被调试的程序在你所指定的调置的断点处停住。 
3.当程序被停住时,可以检查此时你的程序中所发生的事,以及内存状态等。 
4.动态的改变你程序的执行环境。

gdb使用总旨:help指令很强大!多用help!help里面总会有你需要的信息。如果你不知道如何使用help,请在gdb里面输入:help all

一、gdb使用前置条件:编译时加入debug信息。

gcc/g++是在编译时加入-g,其他语言请自行百度。值得注意的是,-g分4个等级:

  1. -g0等于不加-g。即不包含任何信息
  2. -g1只包含最小信息,一般来说只有你不需要debug,只需要backtrace信息,并且真的很在意程序大小,或者有其他保密/特殊需求时才会使用-g1。
  3. –g2为gdb默认等级,包含绝大多数你需要的信息。
  4. –g3包含一些额外信息,例如包含宏定义信息。当你需要调试宏定义时,请使用-g3

二、gdb最常见的几个用法:

1. 调试程序。有几种方法可以在gdb下运行你的程序:

1)    gdb ${你的程序} 进入gdb后,输入run(简写r) ${arg1} ${arg2} … ${argN}

2)    gdb --args ${你的程序} ${arg1} ${arg2} … ${argN} 进入gdb后,运行run。

3)    gdb进入gdb后,输入file ${你的程序}。然后使用set args  ${arg1} ${arg2} … ${argN} 设定好你的程序参数,再运行run。

2. 调试正在运行的程序:

gdb ${你的程序} ${程序pid}

3. 查core:

gdb ${你的程序} ${core文件}

三、gdb常用命令:

1. backtrace:显示栈信息。简写为bt。

2. frame x 切换到第x帧。其中x会在bt命令中显示,从0开始。0表示栈顶。简写为f。

3. up/down x 往栈顶/栈底移动x帧。当不输入x时,默认为1。

4. print x打印x的信息,x可以是变量,也可以是对象或者数组。简写为p。

5. print */&x 打印x的内容/地址。

6. call 调用函数。注意此命令需要一个正在运行的程序。

7. set substitute-path from_path  to_path,替换源码文件路径。当编译机与运行程序的机器代码路径不同时,需要使用该指令替换代码路径,否则你无法在gdb中看到源码。

8. break x.cpp:n 在x.cpp的第n行设置断点,然后gdb会给出断点编号m。命令可简写为b。后面会对break命令进行更详细的解释。

9. command m 设置程序执行到断点m时要看的内容,例如:

command n

>printf "x is %d\n",x

>c

>end

如果command后面没有参数n,则命令被赋给最后一个breakpoint,这其实是说break和command连在一起用,在脚本里用就非常方便了。gdb脚本会在后面详细介绍

10. x /nfu ${addr} 打印addr的内容。addr可以是任何合法的地址表达式,例如0x562fb3d,一个当前有效的指针变量p,或者一个当前有效的变量var的地址&var。nfu是格式,n表示查看的长度,F表示格式(例如16进制或10进制),U表示单位(例如单字节b,双字h,四字w等)。举个栗子:

(gdb) x /3xw 0x562fb3d //这个指令的意思为:以16进制格式显示地址0x562fb3d处3个单位,每个单位四字节的内容。你将得到下列数值:

0x562fb3d:    0x00282ff4    0x080484e0    0x00000000

11. continue 继续运行程序。进入调试模式后,若你已经获取了你需要的信息或者需要程序继续运行时使用。可简写为c

12. until 执行到当前循环完成。可简写为u

13. step 单步调试,步入当前函数。可简写为s

14. next 单步调试,步过当前函数。可简写为n

15. finish 执行到当前函数返回

16. set var x=10 改变当前变量x的值。也可以这样用:set {int}0x83040 = 10把内存地址0x83040的值强制转换为int并赋值为10

17. info locals 打印当前栈帧的本地变量

18. jump使当前执行的程序跳转到某一行,或者跳转到某个地址。由于只会使程序跳转而不会改变栈值,因此若跳出函数到另外的地方 会导致return出错。另外,熟悉汇编的人都知道,程序运行时,有一个寄存器用于保存当前代码所在的内存地址。所以,jump命令也就是改变了这个寄存器中的值。于是,你可以使用“set $pc”来更改跳转执行的地址。如: set $pc = 0x485

19. return: 强制函数返回。可以指定返回值

四、程序中断机制:监视点(watchpoint)、断点(breakpoint)和捕捉点(catchpoint):

1. 监视点。监视点是监视内存中某个地址,当该地址的数据被改变(或者被读取)时,程序交出控制权进入调试器。注意监视点分为软件模式和硬件模式:GDB 使用软件监视点的方式是在单步执行你的程序的同时测试变量的值,所以执行程序的速度会变慢。同时,软件监视点仅在当前线程有效。幸运的是,32 位的 Intel x86 处理器提供了 4 个特殊的调试寄存器用来方便调试程序,GDB 可以使用这些寄存器建立硬件监视点。GDB 总是会优先使用硬件监视点,因为这样不会减慢程序的执行速度。然而,可用的(enable的)硬件监视点的个数是有限的。如果你设置了过多的硬件监视点,当程序从中断的状态变为执行的状态(例如continue,until或者finish)时,GDB 可能无法把它们全部激活。另外,活动的硬件监视点的数量只有在试图继续执行程序时才能知道,也就是说,即使你设置了过多的硬件监视点,gdb在你运行程序之前也不会警告你。

设置监视点的命令有3个,watch(写监视),rwatch(读监视)以及awatch(读写监视)。他们的使用方法一样,皆为以下几种:

1) (r/a)watch x。x是一个变量名。当x的值改变/被读取时,程序交出控制权进入调试器。

2) (r/a)watch 0xN。N为一个有效地址。当该地址的内容变化/被读取时,程序交出控制权进入调试器。

3) (r/a)watch *(int *)0xN。N为一个有效地址。当该地址的中的int指针指向的内容变化/被读取时,程序交出控制权进入调试器。

4) (r/a)watch -l *(int *)0xN。N为一个有效地址。当该地址的中的int指针指向的内容变化/被读取,或者该地址的内容变化/被读取时,程序交出控制权进入调试器。

注意3)和4)的区别在于,当加入-l选项后,会同时监视表达式本身以及表达式指向的内容。

2. 断点是指当执行到程序某一步时,程序交出控制权进入调试器。值得注意的是,break会有一些变体:tbreak,hbreak,thbreak与rbreak。tbreak与break功能相同,只是所设置的断点在触发一次后自动删除。hbreak是一个硬件断点。thbreak则既是一个临时的硬件断点。注意硬件断点需要硬件支持,某些硬件可能不支持这种类型的断点。rbreak稍微特殊一些,它会在匹配正则表达式的全部位置加上断点,后面会有详细讲解。除去rbreak,其他break家族的使用方法如下:

1) (t/h)break x.cpp:y 。在代码x.cpp的第y行加入断点。x.cpp若不指定,则会以当前执行的文件作为断点文件。若程序未执行,则以包含main函数的源代码文件作为断点文件。若x.cpp和y都不指定,则以当前debugger的点作为断点处。

2) (t/h)break 0xN。在地址N处加入断点。N必须为一个有效的代码段(code segment)地址。

3) (t/h)break  x.cpp:func。在x.cpp的func函数入口处加入断点。x.cpp可以不提供直接使用break func。注意由于重载(overload)的存在,因此gdb可能会询问你希望在哪个函数加上断点。你也可以通过指定参数类型来避免该问题,例如break func(int ,char *)

4) (t/h)break  +/-N。在当前运行处的第N行后/前加入断点。

5) rbreak REGEXP。 在所有符合正则表达式REGEXP的函数入口加入断点。例如rbeak EX_* 表示在所有符合以EX_开头的函数入口处加入断点。

注意break后面还有2个可选参数,线程id和条件。线程id指在info threads中的线程序号,而非系统提供的tid。例如break x.cpp:y 2 if (a==24),表示在2号线程的x.cpp的第y行加入断点,并且只有当a的值为24时,程序才会交出控制权进入调试器。

另外,breakpoints可以通过save命令保存,以方便使用者下次再次进入程序调试时不需要重设断点。

3. 捕捉点是当某些事件发生时,程序交出控制权进入调试器。例如catch一个exception,assert,signal,fork甚至syscall。tcatch与catch功能一样,只是所设置的捕捉点在触发一次后自动删除。以后会详细介绍catchpoint。

五、跟踪点(tracepoint):

跟踪点与上面三个断点不同之处在于,它只是跟踪记录信息而不会中断程序的运行。当你的程序是realtime程序,或者与其他的程序有交互时,你可能会希望使用跟踪点达到监视程序而又不破坏程序自身行为的目的。与断点相同的是,跟踪点会保存下在跟踪点时的一些内存信息供使用者查阅,例如数组或者对象。

另外,tracepoints可以通过save命令保存,以方便使用者下次再次进入程序调试时不需要重设这些跟踪点。

六、检查点(checkpoint):

gdb可以保存某一个时间点的程序状态或者说是程序映像,并且稍后又可以返回到这个状态。这个称之为checkpoint。

每个检查点是进程的一个拷贝。这样当一个bug很难重现,而又担心调试过头了又要从头开始重现时,可以在估计要重现这个bug之前,做一个checkpoint,这样即使debug过头了,也可以从这个checkpoint开始,而不用重启整个程序并且期待它重现这个bug(也许需要很久!!)。

但是每个checkpoint有一个唯一的进程id,这个pid与原始程序的pid不同,因此如果程序需要使用pid的信息时,需要慎重考虑。

原文地址:https://www.cnblogs.com/hacker007/p/9549510.html

时间: 2024-10-17 17:18:21

GDB常用命令使用的相关文章

GDB常用命令使用说明(一)

本文由霸气的菠萝原创,转载请注明出处:http://www.cnblogs.com/xsln/p/gdb_instructions1.html 全部关于gdb的文章索引请点这里 GDB(GNU Debugger)是在Unix以及类Unix系统下的调试工具.功能极其强大,几乎涵盖了你所需要的全部功能. GDB主要帮忙你完成下面四个方面的功能: 1.启动你的程序,可以按照你的定制要求随心所欲的运行程序. 2.可让被调试的程序在你所指定的调置的断点处停住. 3.当程序被停住时,可以检查此时你的程序中所

Linux GDB常用命令一栏

Linux GDB 常用命令如下: 1.启动和退出gdb (1)启动:gdb ***:显示一段版权说明: (*** 表示可执行程序名) (2)退出:quit.有的时候输入quit后会出现相关提示:类似于“(y/n)”,输入y 2.显示和查找程序源代码 (1)list :显示10行代码,但是我为什么没有显示成功呢? (2)list 5,10:显示源文件第五行到第十行的代码 (3)list t4.c:5,10:显示源文件中第五行到第十行的代码,在跳是含有多个源文件的次序时使用: (4)list ge

再探gdb常用命令

 前面已经有了一篇对gdb常用命令的总结,见 http://blog.csdn.net/u011848617/article/details/12838875 这里对目前学过的gdb命令进行了较完整的整理. 1.使用gdb调试代码,就要在编译时添加-g选项. 2.gdb -q ------ 启动gdb时不输出版权说明 3.gdb打开文件: (1)gdb filename: (2)先输入gdb,然后在gdb命令行输入file filename. 4.gdb选项(gdb中好多命令都有自己的简写字

gdb常用命令记录

gdb常用命令 最近在研究nginx源码,gdb用于调试非常方便,之前这篇有研究过如何使用gdb调试nginx:https://www.cnblogs.com/yjf512/archive/2012/05/10/2494635.html 最近使用的时候gdb的命令又忘记了.这里复习一下. 这里有很全的资料:https://www.gitbook.com/book/wizardforcel/100-gdb-tips 常用命令 启动项目并断点 start 打临时断点 tb 打断点 b 列出代码 l

Linux调试工具strace和gdb常用命令小结

strace和gdb是Linux环境下的两个常用调试工具,这里是个人在使用过程中对这两个工具常用参数的总结,留作日后查看使用. strace调试工具 strace工具用于跟踪进程执行时的系统调用和所接收的信号,包括参数.返回值.执行时间.在Linux中,用户程序要访问系统设备,必须由用户态切换到内核态,这是通过系统调用发起并完成的. strace常用参数: -c 统计每种系统调用执行的时间.调用次数.出错次数,程序退出时给出报告 -p pid 跟踪指定的进程,可以使用多个-p同时跟踪多个进程 -

gdb常用命令总结

1: 对于在应用程序中加入参数进行调试的方法: 直接用 gdb app -p1 -p2 这样进行调试是不行的. 需要像以下这样使用: #gdb app (gdb) r -p1 -p2 或者在运行run命令前使用set args命令: (gdb) set args p1 p2 可以用show args 命令来查看 2. 加入断点: break <linenumber> break <funcName> break +offset break -offset (在当前行号的前面或后面的

gdb常用命令

在调试程序的时候,gdb是一柄利器,恰当的使用gdb可以解决掉程序的许多bug. gdb并不检查语法错误,那是gcc或者g++的事情,gdb干的是调试的事情. 说明: (1)gdb 程序名 [corefile]之类的是代表命令的用法,[]中间的内容是可选项,即你可以加,也可以不加. (2)如果需要重复执行一条命令,不需要每次都键入命令,gdb记住了最后一个被执行的命令,只要简单的按enter键就可以重复执行最后的命令. 1.  gdb命令 该命令主要用来启动调试. gdb 程序名 [corefi

linux之GDB常用命令汇总

查看gdb的版本号 (1)rpm -q gdb 会显示是否安装gdb及版本号 (2)gdb --version也可以 breakpoint b main; b 20; 设置断点 breakpoint if break 函数名.编号 if xxxx 在xxx的情况下设置的断点才生效 (xxx 例如:变量= 3) cd cd /home/yongchao/ 改变当前工作目录 clear 光标在正要执行的break点的行,然后打clear 删除停止处的断点 info b info b 查看所有的断点

GDB常用命令简介

1.启动调试程序 gdb 调试对象,例如gdb app 2.运行程序 run 或这简写为r 3.设置断点 有几种不同的方式 1)break line 2) break file:line 3) break function:offset 4.中断后继续执行 c 5.显示汇编代码 disassemble 或简写为 disas 结合不同参数达到不同的显示效果,几个经典的用法 disas /m func1 -- 显示函数func1的汇编 disas $pc,+10 -- 显示pc位置开始的10字节汇编