手把手教你玩GDB

时间:2023-01-14 17:06:20

第一部分牛刀小试:启动GDB开始调试

1.       编译带调试信息的可执行程序:用gcc(g++)编译的时候带上-g选项即可

2.       启动GDB开始调试

(1)gdb program       ///最常用的用gdb启动程序,开始调试的方式
(2)gdb program core   ///用gdb查看core dump文件,跟踪程序core的原因
(3)gdb program pid    ///用gdb调试已经开始运行的程序,指定pid即可

3.       应用程序带命令行参数的情况,可以通过下面三种方法启动:

(1)启动GDB的时候,加上--args选项,然后把应用程序和其命令行参数带在后面,具体格式为:gdb --args program args

(2)先按1中讲的方法启动GDB,然后在执行run命令的时候,后面加上参数

(3)先按1中讲的方法启动GDB,然后用set argsarglist设置命令行参数,接下来再执行run(r)命令运行程序

4.       退出GDB:

(1)End-of-File(Ctrl+d)

(2)quit或者q

5.       在GDB调试程序的时候执行shell命令:

(1)shellcommand args(也可以先执行shell命令,GDB会退出到当前shell,执行完command后,然后在shell中执行exit命令,便可回到GDB)

(2)makemake-args(等同于shell makemake-args

6.       在GDB中获取帮助:

(1)在GDB中执行help命令,可以得到如图1所示的帮助信息:

图1 GDB帮助菜单

由图1可以看出,GDB中的命令可以分为八类:别名(aliases)、断点(breakpoints)、数据(data)、文件(files)、内部(internals)、隐含(obscure)、运行(running)、栈(stack)、状态(status)、支持(support)、跟踪点(tracepoints)和用户自定义(user-defined)。

(2)helpclass-name:查看该类型的命令的详细帮助说明

(3)help all:列出所有命令的详细说明

(4)helpcommand:列出命令command的详细说明

(5)aproposword:列出与word这个词相关的命令的详细说明

(6)completeargs:列出所有以args为前辍的命令

7.       infoshow

(1)info:用来获取和被调试的应用程序相关的信息

(2)show:用来获取GDB本身设置相关的一些信息

第二部分 Breakpoint, Watchpoint和Catchpoint

1.       Breakpoints相关命令:(Breakpoint的作用是让程序执行到某个特定的地方停止运行)

(1)设置breakpoint:

a. breakfunction: 在函数funtion入口处设置breakpoint

b. break +offset:在程序当前停止的行向前offset行处设置breakpoint

c. break –offset:在程序当前停止的行向衙offset行处设置breakpoint

d. breaklinenum: 在当前源文件的第linenum行处设置breakpoint

e. breakfilename:linenum: 在名为filename的源文件的第linenum行处设置breakpoint

f. breakfilename:function: 在名为filename的源文件中的function函数入口处设置breakpoint

g. break *address:在程序的地址address处设置breakpoint

h. break:

i. break … ifcond: 代表上面讲到的任意一个可能的参数,在某处设置一个breakpoint,但且仅但condtrue时,程序停下来

j. tbreakargs: 设置一个只停止一次的breakpoints,argsbreak命令的一样。这样的breakpoint当第一次停下来后,就会被自己删除

k. rbreakregex: 在所有符合正则表达式regex的函数处设置breakpoint

(2)info breakpoints [n]:查看第n个breakpoints的相关信息,如果省略了n,则显示所有breakpoints的相关信息

(3)pending breakpoints:是指设置在程序开始调试后加载的动态库中的位置处的breakpoints

a. set breakpoint pending auto: GDB缺省设置,询问用户是否要设置pending breakpoint

b. set breakpoint pending on: GDB当前不能识别的breakpoint自动成为pending breakpoint

c. set breakpoint pending off: GDB当前不能识别某个breakpoint时,直接报错

d. show breakpoint pending:查看GDB关于pending breakpoint的设置的行为(auto, on, off)

(4)breakpoints的删除:

a. clear:清除当前stack frame中下一条指令之后的所有breakpoints

b. clearfunction & clear filename:function: 清除函数function入口处的breakpoints

c. clearlinenum & clear filename:linenum: 清除第linenum行处的breakpoints

d. delete [breakpoints] [range…]:删除由range指定的范围内的breakpoints,range范围是指breakpoint的序列号的范围

(5)breakpoints的禁用、启用:

a. disable [breakpoints] [range…]:禁用由range指定的范围内的breakpoints

b. enable [breakpoints] [range…]:启用由range指定的范围内的breakpoints

c. enable [breakpoints]once [range…]: 只启用一次由range指定的范围内的breakpoints,等程序停下来后,自动设为禁用

d. enable [breakpoints]delete [range…]: 启用range指定的范围内的breakpoints,等程序停下来后,这些breakpoints自动被删除

(6)条件breakpoints相关命令:

a. 设置条件breakpoints可以通过breakif cond来设置,也可以通过conditionbnum expression来设置,在这里首先要通过(1)中介绍的命令设置好breakpoints,然后用condition命令来指定某breakpoint的条件,该breakpoint由bnum指定,条件由expression指定

b. conditionbnum: 取消第bnum个breakpoint的条件

c. ignorebnum count: 第bnum个breakpoint跳过count次后开始生效

(7)指定程序在某个breakpoint处停下来后执行一串命令:

a. 格式:commands [bnum]

… command-list …

end

b. 用途:指定程序在第bnum个breakpoint处停下来后,执行由command-list指定的命令串,如果没有指定bnum,则对最后一个breakpoint生效

c. 取消命令列表:commands [bnum]

end

d. 例子:

break foo if x>0

commands

silent

printf "x is %d\n",x

continue

end

上面的例子含义:当x>0时,在foo函数处停下来,然后打印出x的值,然后继续运行程序

2.       Watchpoints相关命令:(Watchpoint的作用是让程序在某个表达式的值发生变化的时候停止运行,达到‘监视’该表达式的目的)

(1)设置watchpoints:

a. watchexpr: 设置写watchpoint,当应用程序写expr,修改其值时,程序停止运行

b. rwatchexpr: 设置读watchpoint,当应用程序读表达式expr时,程序停止运行

c. awatchexpr: 设置读写watchpoint, 当应用程序读或者写表达式expr时,程序都会停止运行

(2)info watchpoints:查看当前调试的程序中设置的watchpoints相关信息

(3)watchpoints和breakpoints很相像,都有enable/disabe/delete等操作,使用方法也与breakpoints的类似

3.       Catchpoints相关命令:(catchpoints的作用是让程序在发生某种事件的时候停止运行,比如C++中发生异常事件,加载动态库事件)

(1)设置catchpoints:

a. catchevent: 当事件event发生的时候,程序停止运行,这里event的取值有:

1)throw: C++抛出异常

2)catch: C++捕捉到异常

3)exec: exec被调用

4)fork: fork被调用

5)vfork: vfork被调用

6)load:加载动态库

7)loadlibname: 加载名为libname的动态库

8)unload:卸载动态库

9)unloadlibname: 卸载名为libname的动态库

10)syscall [args]:调用系统调用,args可以指定系统调用号,或者系统名称

b. tcatchevent: 设置只停一次的catchpoint,第一次生效后,该catchpoint被自动删除

(2)catchpoints和breakpoints很相像,都有enable/disabe/delete等操作,使用方法也与breakpoints的类似

第三部分常用命令介绍

1.         attach process-id/detach

(1)attachprocess-id: 在GDB状态下,开始调试一个正在运行的进程,其进程ID为process-id

(2)detach:停止调试当前正在调试有进程,与attach配对试用

2.        kill

(1)基本功能:杀掉当前GDB正在调试的应用程序所对应的子进程

(2)如果想不退出GDB而对当前正在调试的应用程序重新编译、链接,可以在GDB中执行kill杀掉子进程,等编译、链接完后,再重新执行run,GDB便可加载新的可执行程序启动调试

3.         多线程程序调试相关:

(1)threadthreadno:切换当前线程到由threadno指定的线程

(2)info threads:查看GDB当前调试的程序的各个线程的相关信息

(3)thread apply [threadno] [all]args:对指定(或所有)的线程执行由args指定的命令

4.         多进程程序调试相关(fork/vfork):

(1)缺省方式:fork/vfork之后,GDB仍然调试父进程,与子进程不相关

(2)set follow-fork-modemode:设置GDB行为,modeparent时,与缺省情况一样;modechild时,fork/vfork之后,GDB进入子进程调试,与父进程不再相关

(3)show follow-fork-mode:查看当前GDB多进程跟踪模式的设置

5.         step & stepi

(1)step [count]:如果没有指定count, 则继续执行程序,直到到达与当前源文件不同的源文件中时停止;如果指定了count,则重复行上面的过程count

(2)stepi [count]:如果没有指定count, 继续执行下一条机器指令,然后停止;如果指定了count,则重复上面的过程count

(3)step比较常见的应用场景:在函数func被调用的某行代码处设置断点,等程序在断点处停下来后,可以用step命令进入该函数的实现中,但前提是该函数编译的时候把调试信息也编译进去了,负责step会跳过该函数。

6.         next & nexti

(1)next [count]:如果没有指定count, 单步执行下一行程序;如果指定了count,单步执行接下来的count行程序

(2)nexti [count]:如果没有指定count, 单步执行下一条指令;如果指定了count,单步执行接下来的count条执行

(3)stepinexti的区别:nexti在执行某机器指令时,如果该指令是函数调用,那么程序执行直到该函数调用结束时才停止。

7.         continue [ignore-count]: 唤醒程序,继续运行,至到遇到下一个断点,或者程序结束。如果指定ignore-count,那么程序在接下来的运行中,忽略ignore-count次断点。

8.         finish & return

(1)finish:继续执行程序,直到当前被调用的函数结束,如果该函数有返回值,把返回值也打印到控制台

(2)return [expression]:中止当前函数的调用,如果指定了expression,把expresson值当做当前函数的返回值;如果没有,直接结束当前函数调用

9.         信号的处理

(1)info signals &info handle:打印所有的信号相关的信息,以及GDB缺省的处理方式

(2)handlesignal keywords: 设置GDB对具体某个信号的处理方式。signal可以为信号整数值,也可以为SIGSEGV这样的符号。keywords的取值有:

a. stopnostop:nostop表示当GDB收到指定的信号,不会应用停止程序的执行,只会打印出一条收到信号的消息,因此,nostop也暗含了下面的print;而stop则表示,当GDB收到指定的信号,停止应用程序的执行。

b. printnoprint:print表示如果收到指定的信号,打印出一条信息;noprintprint表示相反的意思

c. passnopasspass表示如果收到指定的信号,把该信号通知给应用程序;nopass表示与pass相反的意思

d. ignorenoignore:ignorenopass同义,同理,noignorepass同义

第四部分调用栈(Call Stack)

1.       查看调用栈信息:

a. backtrace:显示程序的调用栈信息,可以用bt缩写

b. backtracen: 显示程序的调用栈信息,只显示栈顶n桢(frame)

c. backtrace -n:显示程序的调用栈信息,只显示栈底部n桢(frame)

d. set backtrace limitn: 设置bt显示的最大桢层数

e. where,info stack:都是bt的别名,功能一样

2.       选择某一桢进行查看:

a. framen: 查看第n桢的信息

b. frameaddr: 查看pc地址为addr的桢的相关信息

c. upn: 查看当前桢上面第n桢的信息

d. downn: 查看当前桢下面第n桢的信息

3.       frame信息内容:

a. 用backtraceframen或者frameaddr得到的简要信息内容:

(1)桢序号(Frame number)

(2)函数名

(3)Program counter(除非set print address off)(在程序当前执行到的那一桢,PC不会被显示)

(4)源代码文件名和行号

(5)函数的参数名和传入的值

b. 用info frameinfo framen或者info frameaddr得到的详细的信息内容:

(1)当前桢的地址

(2)下一桢的地址

(3)上一桢的地址

(4)源代码所用的程序的语言(c/c++)

(5)当前桢的参数的地址

(6)当前相中局部变量的地址

(7)PC(program counter)

(8)当前桢中存储的寄存器

4.       info args:查看当前桢中的参数

5.       info locals:查看当前桢中的局部变量

6.       info catch:查看当前桢中的异常处理器(exception handlers)

第五部分数据和源代码(Data and Source Code)

1.       list命令(缩写为l):

(1)listlinenum: 打印当前文件中第linenum行周围的源代码

(2)listfunction: 打印function函数周围的源代码

(3)list:在上一次使用list命令的基础上,再多打印一些源代码

(4)list -:打印和上一次使用list命令一样的源代码

(5)set listsizecount: 设置list命令显示源代码的行数

(6)show listsize:查看list命令显示

2.       用edit命令在GDB模式下编辑源代码:

(1)选择合适的编辑器,gdb会选择/bin/ex做为源代码编辑器,有些linux发行版上可能会没有安装/bin/ex,可以把编辑器修改为比较常见的vim,具体做法为:有启动gdb之前,在命令行执行export EDITOR=/usr/bin/vim(或者可以在.profile中设置EDITOR这个变量的值为/usr/bin/vim,这样就不用每次启动gdb的时候都去设置一下了)

(2)edit:编辑当前文件

(3)editnumber: 编辑当前文件的第number

(4)editfunction: 编辑当前文件的function函数

(5)editfilename: number: 编辑名为filename的文件的第number

(6)editfilename: function: 编辑名为filename的文件的function函数

3.       设置源代码目录

(1)directorydirname: 设置当前调试的程序的源代码目录为dirname

(2)directory:将当前调试的程序的源代码目录清空

(3)show directories:打印当前调试的程序的源代码目录

4.       print命令打印数据:

(1)printexpr: 打印表达式expr的值

(2)print /f expr:以f指定的格式打印表达式expr的值

(3)print:打印上一次打印的表达式的值

(4)print /f:以f指定的形式打印上一次打印的表达式的值

(print支持的格式有:x-16进制整数,d-10进制整数,u-10进制无符号整数,o-8进制整数,t-2进制整数,a-地址形式整数,c-字符常量整数,f-浮点数)

5.       GDB支持的表达式:

(1)Any kind of constant, variable or operator defined by the programming language you are using is valid in an expression inGDB.

(2)@address:把address指定的内存当作数组,语法为p *array@len

(3)file::variable:指定变量varialbe被定义的文件file

(4)function::varable:指定变量variable被定义的函数function

(5){type}address: 把address指定的内存解释为type类型(类似于强制转型,更加强)

6.       打印内存:x /nfu addr:

(1)n:重复次数,缺省是1

(2)f:打印格式,与print的相同的,还有s-C风格字符串,i-机器指令,缺省是x

(3)u:打印单位大小,b-byte,h-halfwords(2字节),w-words(4字节),g-Giant words(8字节)

7.       自动打印:

(1)display /f expr|addr:以f为格式,打印expr或者addr

(2)undisplaydnumsdelete display dnums:删除第dnums个display点

(3)disable displaydnums:禁用第dnums个display点

(4)enable displaydnums:启用第dnums个display点

(5)info display:查看所有的display点

8.       打印选项:

a. set printfield: 打开field选项

b. set printfield on: 打开field选项

c. set printfield off: 关闭field选项

d. show printfield: 查看field选项的打开、关闭情况

(1)set print array:以一种比较好看的方式打印数组,缺省是关闭的

(2)set print elementsnum-of-elements:设置GDB打印数据时显示元素的个数,缺省为200,设为0表示不限制(unlimited)

(3)set print null-stop:设置GDB打印字符数组的时候,遇到NULL时停止,缺省是关闭的

(4)set print pretty:设置GDB打印结构的时候,每行一个成员,并且有相应的缩进,缺省是关闭的

(5)set print object:设置GDB打印多态类型的时候,打印实际的类型,缺省为关闭

(6)set print static-members:设置GDB打印结构的时候,是否打印static成员,缺省是打开的

(7)set print vtbl:以漂亮的方式打印C++的虚函数表,缺省是关闭的

9.       寄存器:

(1)info registers:查看当前桢中的各个寄存器的情况

(2)info registersregname: 查看指定的寄存器

(3)各个寄存器:

10.   内存copy:

(1)dump [format]memory filename start_addr end_addr

(2)append [binary]memory filename start_addr end_addr

(3)restorefilename [binary] bias start end

11.   在GDB中定义宏:

(1)info macromacro:查看宏macro的定义

(2)macro definemacro replacement-list:(还没实现)

(3)macro definemacro(arglist) replacement-list:(还没实现)

(4)macro undefmacro:(还没实现)

12.   修改程序的运行(Altering Execution)

(1)修改变量值:

a. printv=value: 修改变量值的同时,把修改后的值显示出来

b. set [var]v=value: 修改变量值,需要注意如果变量名与GDB中某个set命令中的关键字一样的话,前面加上var关键字

c. whatisv: 查看变量类型

(2)signalsignal: 向程序发送信号signal,signal可以是信号的符号或数字形式,如果signal=0,那么程序将会继续运行,程序不会收到任何信号。

(3)return [expression]:中断函数执行,从当前位置直接返回。(注意:finish是把函数运行完,再返回,return是直接返回。)

(4)callexpr: 在GDB中调用应用程序中的函数

13.   用户自定义命令:

(1)定义一个命令

definecommandname

        

end

(2)条件语句:

if cond-expr

else

end

(4)循环语句:

whilecond-expr

end

(5)定义一个命令的文档信息,在helpcommandname的时候可以显示:

documentcommandname

end

(6)$arg0…$arg9:表示命令行参数,最多10

7help user-defined:查看所有的用户自定义命令

8show usercommandname:查看自定义命令commandname的定义

9helpcommandname:查看自定义命令commandname的帮助信息

10show max-user-call-depth:查看用户自定义命令的最大递归调用深度

11set max-user-call-depth:设置用户自定义命令的最大递归调用深度

转载自:http://www.wuzesheng.com

手把手教你玩GDB的更多相关文章

  1. 手把手教你玩转SOCKET模型之重叠I/O篇(下)

    四.     实现重叠模型的步骤 作 了这么多的准备工作,费了这么多的笔墨,我们终于可以开始着手编码了.其实慢慢的你就会明白,要想透析重叠结构的内部原理也许是要费点功夫,但是只是学会 如何来使用它,却 ...

  2. 转:变手把手教你玩转SOCKET模型之重叠I/O篇

    手把手教你玩转SOCKET模型之重叠I/O篇 “身为一个初学者,时常能体味到初学者入门的艰辛,所以总是想抽空作点什么来尽我所能的帮助那些需要帮助的人.我也希望大家能把自己的所学和他人一起分享,不要去鄙 ...

  3. 手把手教你玩转 CSS3 3D 技术

    css3的3d起步 要玩转css3的3d,就必须了解几个词汇,便是透视(perspective).旋转(rotate)和移动(translate).透视即是以现实的视角来看屏幕上的2D事物,从而展现3 ...

  4. 手把手教你玩转CSS3 3D技术

    手把手教你玩转 CSS3 3D 技术   要玩转css3的3d,就必须了解几个词汇,便是透视(perspective).旋转(rotate)和移动(translate).透视即是以现实的视角来看屏幕上 ...

  5. 知识全聚集 .Net Core 技术突破 | 我用C#手把手教你玩微信自动化一

    知识全聚集 .Net Core 技术突破 | 我用C#手把手教你玩微信自动化一 教程 01 | 模块化方案一 02 | 模块化方案二 03 | 简单说说工作单元 其他教程预览 分库分表项目实战教程 G ...

  6. 完毕port(CompletionPort)具体解释 - 手把手教你玩转网络编程系列之三

       手把手叫你玩转网络编程系列之三    完毕port(Completion Port)具体解释                                                    ...

  7. 手把手教你玩微信小程序跳一跳

    最近微信小程序火的半边天都红了,虽然不会写,但是至少也可以仿照网上大神开发外挂吧!下面手把手教妹纸们(汉纸们请自觉的眼观耳听)怎么愉快的在微信小游戏中获得高分. 废话不多说,咱们这就发车了!呸!咱们这 ...

  8. Apache Beam实战指南 | 手把手教你玩转KafkaIO与Flink

    https://mp.weixin.qq.com/s?__biz=MzU1NDA4NjU2MA==&mid=2247492538&idx=2&sn=9a2bd9fe2d7fd6 ...

  9. 手把手教你玩转nginx负载均衡(五)----配置后端服务器组

    引言 在前面几篇中,我们成功的搭建起了一台nginx服务器,所以我们要重复前面的步骤,把服务器的数量增加到3台以上,我这里已经建好了另外两台,分别是centos7-22,centos7-23,对应的i ...

随机推荐

  1. Epplus

    简介:Epplus是一个使用Open Office XML(Xlsx)文件格式,能读写Excel 2007/2010文件的开源组件 功效:支持对excel文档的汇入汇出,图表(excel自带的图表基本 ...

  2. asp.net form身份认证不定时认证失败的问题 排查

    1.网站出现form认证不定时认证失败.登陆过后 每隔一会儿就需要重新登陆.首先检查的是form身份认证票据设置的时间(正常) 然后检查加密后的身份认证信息写入的cookie的失效时间(正常) 2.这 ...

  3. linux之LVM

    一.简介 LVM是逻辑盘卷管理(Logical Volume Manager)的简称,它是Linux环境下对磁盘分区进行管理的一种机制,LVM是建立在硬盘和分区之上的一个逻辑层,来提高磁盘分区管理的灵 ...

  4. VB .NET周期实现

    这里仅提供一个方案,当然会有比本方案更好的,欢迎提供. 简介 在vb.net实现周期调度的问题时(就是间隔固定的时间做什么事情),我们最先想到的一定是(反正我是)利用timer(定时器)来做这个计时的 ...

  5. 【安全测试】 WebScarab安装方法

    Webscarab同样需要java环境,下载j2_webscarab-installer.jar包. 1.进入cmd,执行java -jar j2_webscarab-installer.jar命令( ...

  6. csuoj 1396: Erase Securely

    http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1396 1396: Erase Securely Time Limit: 1 Sec  Memory ...

  7. jQuery的单选,复选,下拉

    单选 获取 ($('input:first').attr('vlaue')); 选中 ($('input:checked').val()); 属性值的设置$().val(属性值)$('input:fi ...

  8. linux apache 自动监护脚本

    1 首先安装curl yum install curl 2 编写shell vi restart_apache.sh 写入一下内容 #!/bin/bashURL="http://127.0. ...

  9. LINQ 101——分区、Join、聚合

    一.Partitioning 分区 Take 例1:取前3个数 static void Linq1() { , , , , , , , , , }; ); Console.WriteLine(&quo ...

  10. Linux on ASUS N550JK4700

    实际上,ASUS N550JK对Ubuntu 14.04的兼容性是相当好的,包括无线网卡.蓝牙.键盘背光的调节.触摸板的开关.音量的键盘调节都是安装后无需配置直接可以使用的,这是出乎意料的,因为这些功 ...