视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
常用GDB调试方法
2025-10-05 05:17:27 责编:小OO
文档
1.什么是GDB

GDB是GNU开源组织发布的一个强大的UNIX下的C/C++程序调试工具。虽然GDB自身并没有Windows上大多数IDE的调试工具的高可视化和图形化功能,但命令行式调试也具有其很大的优点,如果希望在GDB上提升可视化功能,可以使用vim的gdb插件对gdb进行加强。

顺便提一下调试程序的几大功能:

a)自定义方式启动程序;

b)可以设置断点,使程序在指定的断点处停住;

c)当程序停住时,可以查看程序的运行时数据;

d)可以修改程序的运行时数据;

2.GDB与编译器的-g和-ggdb参数

cc/gcc/g++使用-g参数可以在编译时利用操作系统的“原生格式(native format)”生成调试信息。这些信息GDB可以直接利用,当然其它的调试工具也能够直接利用。

-g参数是分级别的:

a) -g2

使用-g的默认的级别,此时产生的调试信息包括扩展的符号表、行号、局部或外部变量信息。如果不使用,则只有内存地址信息,没有响应的标识信息;

b)-g3

包含级别-g2中的所有调试信息,以及源代码中定义的宏;

c)-g1

级别1(-g1)不包含局部变量和与行号有关的调试信息,因此只能够用于回溯跟踪和堆栈转储之用。回溯跟踪指的是监视程序在运行过程中的函数调用历史,堆栈转储则是一种以原始的十六进制格式保存程序执行环境的方法,两者都是经常用到的调试手段。

-ggdb参数能够为GDB生成更为丰富的调试信息,与-g相同,也有3个级别,如果希望调试宏,则可以使用-ggdb3。但与-g不同的是,-ggdb生成的信息只能被GDB使用,而不能被其它调试工具使用。

3.使用GDB启动调试

使用GDB启动调试的方法有一下几种(只是关联上调试目标程序,并没有开始运行目标程序):

a)gdb

也就是你的执行文件,要在PATH环境变量下能搜索到,一般在当前目录下;

b)gdb core_file

用gdb同时调试一个运行程序和core文件,core是程序非法执行后core dump后产生的文件。启动后,gdb将加载core文件保存的堆栈信息,使用bt命令可以查看堆栈信息,后面也将对此进行详细说明;

c)gdb

用gdb调试正在运行的进程,是正在运行的进程ID。gdb能自动attach到这个进程上,其中要在PATH环境变量下能够搜索到。也可以使用gdb attach

4.查看源代码

使用list命令,也可以使用缩写l。

list [linenum]

查看指定行[linenum]附近的代码。

5.设置断点(Breakpoint)

GDB提供break命令来设置断点,有以下几种设置断点的方法:

a)break

在进入指定函数时停住。C++中也可以使用class::function,或者类似function(type,type)的方式来指定函数;

b)break :

在进入指定源文件的函数时停住。

c)break

在运行到指定行时停住。

d)break :

在运行到指定源文件的指定行时停住。

e)break 

在当前行号的前后指定offset处停住,例如当前行为10,运行break +100表示在110处设置断点,运行break -10则表示在90处设置断点;

f)break *

在程序运行到内存地址

处停住。

g)break 

break后什么都没有,表示在下一条指令处停住。

h)break [where] if

在条件成立时停住。[where]可以是上述任何break的参数,也可以不设置,不设置则表示条件成立的下一条指令处停住。例如,break if i=100,表示当i等于100时停住程序。

i)commands

>[command_list]

>end

为断点设置自动执行命令。例如:

(gdb) commands 2

>print n

>end

表示在第2个断点时,执行print n操作。

6.查看断点(Breakpoint)

info breakpoints [n]

info break [n]

info b [n]

以上[n]表示第n个断点,如果没有,则显示所有断点。

7.删除/修改断点(Breakpoint)

GDB提供四个命令来维护断点:delete、clear、disable、enable。

a)delete

删除指定断点。

delete [breakpoint num]

delete [breakpoint num range]

[breakpoint num]为断点号,[breakpoint num range]为断点号范围。如果不指定断点号,则为删除所有断点

b)clear

清除断点

clear  清除当前位置断点

clear : 

clear                     清除指定函数位置上的断点

clear :

clear                     清除指定行位置上的断点

c)disable

禁用断点,不删除。

d)enable

将禁用的断点启动。

 对于条件断点,可以使用condition  修改断点条件。

 可以使用ignore  来忽略指定断点

8.设置观察点(Watchpoint)

观察点一般来观察某个表达式(变量也是一种表达式)的值是否有变化了,如果有变化,马上停住程序。我们有下面的几种方法来设置观察点:

a)watch

为表达式(变量)expr设置一个观察点。一量表达式值有变化时,马上停住程序。

b)rwatch

当表达式(变量)expr被读时,停住程序。

c)awatch

当表达式(变量)的值被读或被写时,停住程序。

9.运行调试程序

a)set args [params]

设置程序运行参数,例如set args param1 param2

b)run/r

运行调试程序。        

10.单步调试

a)step/s [count]

单步跟踪,如果有函数调用,他会进入该函数。进入函数的前提是,此函数被编译有debug信息。很像VC等工具中的step in。后面可以加count也可以不加,不加表示一条条地执行,加则表示执行后面的count条指令,然后再停住。

b)next/n [count]

同样单步跟踪,如果有函数调用,他不会进入该函数。很像VC等工具中的step over。后面可以加count也可以不加,不加表示一条条地执行,加则表示执行后面的count条指令,然后再停住。

c)finish [count]

运行程序,直到当前函数完成返回。并打印函数返回时的堆栈地址和返回值及参数值等信息。

d)until/u [count]

当你厌倦了在一个循环体内单步跟踪时,在循环指令上使用这个命令可以运行程序直到退出循环体。

e)continue/c [ignore-count]

当程序被停住了,你可以用continue恢复程序运行,直到程序结束,或是下一个断点到来。ignore-count表示忽略其后的断点次数。

11.查看运行时数据

a)print

打印变量,可以使用缩写p。

i.p

基本用法,打印变量或者表达式,如p i、p i+j。

ii.p/

使用指定格式打印。支持的格式包括:

x  按十六进制格式显示变量。

d  按十进制格式显示变量。

u  按十六进制格式显示无符号整型。

o  按八进制格式显示变量。

t  按二进制格式显示变量。 

a  按十六进制格式显示变量。

c  按字符格式显示变量。

f  按浮点数格式显示变量。

iii.p *@

指定长度打印数组。

如有int* array = new int[100];

则可以使用 p *array@10,查看数组前10个元素的数值。

b)examine

查看指定内存地址中的数据,可以使用缩写x,可以在gdb中使用help x查看帮助。

使用方式为:

x/

支持的格式除了print中的格式外,还包括:

n   是一个正整数,表示显示内存的长度,也就是说从当前地址向后显示几个地址的内容。

u 表示从当前地址往后请求的字节数,如果不指定的话,GDB默认是4个bytes。u参数可以用下面的字符来代替,b表示单字节,h表示双字节,w表示四字 节,g表示八字节。当我们指定了字节长度后,GDB会从指内存定的内存地址开始,读写指定字节,并把其当作一个值取出来。

c)display

用于自动显示, 当程序停住时,或是在你单步跟踪时,这些变量会自动显示。使用方式为:

display

display/

display/

支持的格式i和s,可以help display查看。

12.修改运行时数据

a)修改运行时变量

set =

set var =

如果变量名与gdb的环境变量名冲突时,则需要加var前缀来说明这是要设置一个变量。

b)强制函数返回

return

return

如果函数需要返回值,则指定

c)强制调用函数

call

13.调试多线程

多线程调试常用的命令如下:

a)info thread

查看线程信息。

b)thread

切换到指定ID的线程。

c)break thread all

对所有经过的线程都设置断点。

d)set scheduler-locking off|on|step

在使用step或者continue命令调试当前被调试线程的时候,其他线程也是同时执行的,怎么只让被调试程序执行呢?通过这个命令就可以实现这个需求。 

off   不锁定任何线程,也就是所有线程都执行,这是默认值。

on   只有当前被调试程序会执行。

step  在单步的时候,除了next过一个函数的情况(熟悉情况的人可能知道,这其实是一个设置断点然后continue的行为)以外,只有当前线程会执行。下载本文

显示全文
专题