如何用GDB进行调试

如何用GDB进行调试,第1张

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

(在当前行号的前面或后面的offset行停住。)

break filename:linenum

在源文件filename的linenum行处停住。

break filename:function

在源文件filename的function函数的入口处停住。

break ... if

...可以是上述的参数,condition表示条件,在条件成立时停住。比如在循环境体中,可以设置 break if i=100,表示当i为100时停住程序。

3. 查看运行时的堆栈:

使用bt命令

4. 打印某个变量的值:

print val

5. 单步: n

继续运行: c

step

单步跟踪,如果有函数调用,他会进入该函数。

next

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

set step-mode

set step-mode on

打开step-mode模式,于是,在进行单步跟踪时,程序不会因为没有debug信息而不停住。这个参数有很利于查看机器码。

set step-mod off

关闭step-mode模式。

finish

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

until 或 u

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

6.在GDB中执行shell命令:

 在gdb环境中,你可以执行UNIX的shell的命令,使用gdb的shell命令来完成:

 eg. shell make

7. 运行环境

可设定程序的运行路径。

show paths 查看程序的运行路径。

set environment varname [=value] 设置环境变量。如:set env USER=hchen

show environment [varname] 查看环境变量。

8.观察点(WatchPoint)

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

watch

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

rwatch

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

awatch

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

info watchpoints

列出当前所设置了的所有观察点。

9. 维护breakpoint

clear

清除所有的已定义的停止点。

clear func

清除所有设置在函数上的停止点。

delete [breakpoints] [range...]

删除指定的断点,breakpoints为断点号。如果不指定断点号,则表示删除所有的断点。range 表示断点号的范围(如:3-7)。其简写命令为d。

比删除更好的一种方法是disable停止点,disable了的停止点,GDB不会删除,当你还需要时,enable即可,就好像回收站一样。

disable [breakpoints] [range...]

disable所指定的停止点,breakpoints为停止点号。如果什么都不指定,表示disable所有的停止 点。简写命令是dis.

enable [breakpoints] [range...]

enable所指定的停止点,breakpoints为停止点号。

10、程序变量

查看文件中某变量的值:

file::variable

function::variable

可以通过这种形式指定你所想查看的变量,是哪个文件中的或是哪个函数中的。例如,查看文件f2.c中的全局变量x的值:

gdb) p 'f2.c'::x

查看数组的值

有时候,你需要查看一段连续的内存空间的值。比如数组的一段,或是动态分配的数据的大小。你可以使用GDB的“@” *** 作符,“@”的左边是第一个内存的地址的值,“@”的右边则你你想查看内存的长度。例如,你的程序中有这样的语句:

int *array = (int *) malloc (len * sizeof (int))

于是,在GDB调试过程中,你可以以如下命令显示出这个动态数组的取值:

p *array@len

如果是静态数组的话,可以直接用print数组名,就可以显示数组中所有数据的内容了。

11.输出格式

一般来说,GDB会根据变量的类型输出变量的值。但你也可以自定义GDB的输出的格式。例如,你想输出一个整数的十六进制,或是二进制来查看这个整型变量的中的位的情况。要做到这样,你可以使用GDB的数据显示格式:

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

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

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

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

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

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

c 按字符格式显示变量。

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

(gdb) p i

$21 = 101

(gdb) p/a i

$22 = 0x65

(gdb) p/c i

$23 = 101 'e'

(gdb) p/f i

$24 = 1.41531145e-43

(gdb) p/x i

$25 = 0x65

(gdb) p/t i

$26 = 1100101

11.查看内存

使用examine命令(简写是x)来查看内存地址中的值。x命令的语法如下所示:

x/

n、f、u是可选的参数。

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

f 表示显示的格式,参见上面。如果地址所指的是字符串,那么格式可以是s,如果地十是指令地址,那么格式可以是i。

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

n/f/u三个参数可以一起使用。例如:

命令:x/3uh 0x54320 表示,从内存地址0x54320读取内容,h表示以双字节为一个单位,3表示三个单位,u表示按十六进制显示。

12.自动显示

你可以设置一些自动显示的变量,当程序停住时,或是在你单步跟踪时,这些变量会自动显示。相关的GDB命令是display。

display

display/

display/ expr

expr是一个表达式,fmt表示显示的格式,addr表示内存地址,当你用display设定好了一个或多个表达式后,只要你的程序被停下来,GDB会自动显示你所设置的这些表达式的值。

格式i和s同样被display支持,一个非常有用的命令是:

display/i $pc

undisplay

delete display

删除自动显示,dnums意为所设置好了的自动显式的编号。

disable display

enable display

disable和enalbe不删除自动显示的设置,而只是让其失效和恢复。

info display

查看display设置的自动显示的信息。GDB会打出一张表格,向你报告当然调试中设置了多少个自动显示设置,其中包括,设置的编号,表达式,是否enable。

13. 设置显示选项

set print address

set print address on

打开地址输出,当程序显示函数信息时,GDB会显出函数的参数地址。系统默认为打开的,

show print address

查看当前地址显示选项是否打开。

set print array

set print array on

打开数组显示,打开后当数组显示时,每个元素占一行,如果不打开的话,每个元素则以逗号分隔。这个选项默认是关闭的。与之相关的两个命令如下,我就不再多说了。

set print array off

show print array

set print elements

这个选项主要是设置数组的,如果你的数组太大了,那么就可以指定一个来指定数据显示的最大长度,当到达这个长度时,GDB就不再往下显示了。如果设置为0,则表示不限制。

show print elements

查看print elements的选项信息。

set print null-stop

如果打开了这个选项,那么当显示字符串时,遇到结束符则停止显示。这个选项默认为off。

set print pretty on

如果打开printf pretty这个选项,那么当GDB显示结构体时会比较漂亮。

14.关于显示源码list

目录、终端类型以及程序运行的搜索目录这些信息。通常你用shell设置的环境变量会被所有你运行的其他程序所继承。调试时,不需要反复启动GDB就可以使用一个修改的环境变量试着运行程序,是很有用的。

path directory

在传递给程序的PATH环境变量(可执行程序的搜索路径)前,添加directory。GDB所使用的PATH值不会被更改。可以指定若干的目录名,使用空格或系统相关的分隔符(UNIX上是“:”,MS-DOS和MS-Windows上是“”)分隔它们。如果directory已经在PATH中了,就把它移到前面,以使它可以被立即搜索到。 可以使用字符串“$cwd”,在GDB搜索路径时,引用当前工作目录。如果使用“.”代替的话,它引用的是由执行path命令指定的目录。在添加directory到搜索路径之前,GDB在directory参数中替换“.”(使用当前路径)。

show path

显示可执行文件的搜索路径列表(PATH环境变量)。

show environment [varname]

打印程序启动时惯于它的环境变量varname的值。要是没有给出varname,就打印所有惯于程序的环境变量的名和它的值。可以用env简写environment。

set environment varname [=value]

给环境变量varname赋值为value。变量值的更改仅针对于程序,不会影响GDB本身。value可以是任何字符串——环境变量值只能是字符串,对它的任何解释都由程序本身提供。value参数是可选的。如果去除的话,变量会被赋予一个null值。 例如这个命令:

set env USER = foo

告诉GDB,在随后的run时,它的用户是一个名叫“foo”的(“=”前后使用的空格是为了清晰,实际上是不需要的)。

unset environment varname

从传递给程序的环境中移除变量varname。这与“set environment varname=”不同,它是从环境中移出变量,而不是给它赋一个空值。

警告:在UNIX系统中,如果有SHELL环境变量的话,GDB使用的是它指定的shell(没有的话使用/bin/sh)。如果你的SHELL环境变量指定了一个运行初始化文件(如C-Shell的“.cshrc”或者是BASH的“.bashrc”)的shell,你设置在那个文件中的任何变量,都会对你的程序有所影响。你可能希望把这些环境变量的设置移到仅在你注册时运行的文件中去,这样的文件有“.login”或“.profile”。

4.5 程序的工作目录

每次使用run启动的程序,都GDB的当前工作目录继承为它的工作目录。GDB的工作目录最初是继承自它的父进程(通常是shell),不过,你可以在GDB中使用cd命令指定一个新的工作目录。

GDB的工作目录也担当着GDB *** 作的指定文件命令的默认目录。参见指定文件的命令一节。

cd directory

设置GDB的工作目录为directory。

pwd

打印GDB的当前工作目录。

找到正被调试的进程的当前工作目录,通常是做不到的(因为一个程序可以在它运行的时候改变它的目录)。如果你工作在GDB可以被配置为带有“/proc”支持的系统上的话,你可以利用info proc命令(见18.1.3 SVR4进程信息一节)找到debuggee的当前工作目录。

4.6 程序的输入输出

默认情况下,GDB下运行的程序作输入输出的终端,与GDB所使用的是相同的。GDB把终端转换为它自己的终端方式与你交互,不过,它记录你的应用程序所使用的终端方式,当你继续运行你的程序时,它再切换回来。

info terminal

显示由GDB记录下来的程序所使用的终端模式的信息。

可以使用run命令,利用shell的重定向,重定向程序的输入和/或输出。

启动程序,驱使他的输出到文件“outfile”。

另外一种指定程序在何处做输入输出的方式是使用tty命令。这个命令接受一个作为参数的文件名,并使这个文件成为之后run命令的默认重定向目标。它也为子进程、之后的run命令重置控制终端。例如:

指示后续用run命令启动的进程默认在终端“/dev/ttyb”上作输入输出,并且拿这个作为它们的控制终端。

在run中明确的重定向,优先于tty对输入/输出设备的影响,但是并不对控制终端有影响。

当使用tty命令或在run命令中重定向输入时,只有程序的输入会受到影响。GDB的输入依然来自你的终端。tty是set inferior-tty的别名。

可以使用show inferior-tty命令告诉GDB,显示将来程序运行会被使用的终端的名字。

set inferior-tty /dev/ttyb

设置正被调试的程序的tty为/dev/ttyb。 tty /dev/ttyb run >outfile

show inferior-tty

显示正被调试的程序的当前tty。

4.7 调试某个已运行的进程

attached process-id

这个命令附着到一个正在GDB以外运行的进程。(info文件显示活动目标)这个命令带有一个process-id参数。要找到某个UNIX进程的process-id,通常的方式是使用ps工具,或者使用“jobs –l”shell命令。

attached命令执行之后,第二次按RET的话,是不会被重复的。

为了使用attached,程序必须运行在一个支持进程的环境下。例如:对于在缺乏 *** 作的bare-board目标上的程序,attached是不会工作的。也必须得有发送信号的权限。

当使用attached的时候,调试器首先定位当前目录中正运行在进程中的程序,然后(如果没有发现这个程序)查看元文件搜索路径(参见指定源文件目录一节)。你也可以利用file命令装载程序。参见指定文件的命令一节。

准备好要调试的指定进程后,所做的第一件事就是停止进程。检查与修改被附着的进程,可以使用平常使用run启动进程时能够用到的所有命令。可以插入断点;可以单步调试并继续;可以修改存储器。如果你愿意让进程继续运行的话,你可以在将GDB附着到进程之后使用continue命令。

detach

当对被附着的进程的调试完成时,可以使用detach命令,把它从GDB的控制下释放出来。分离进程而继续执行。detach命令之后,那个进程与GDB再一次变得完全独立,并且准备附着另外一个进程,或者使用run命令启动一个。detach命令执行之后,再按RET的话,是不会被重复的。

当已附着到一个进程时,退出GDB或使用run命令,会杀掉那个进程

win下把 gdb 全部放到 c:\windows\system32 下面

在cmd下启动 gdb。

或者 你把 gdb 解压到某个文件夹比如: d:\gdb

然后在系统环境变量里设置 PATH 变量,在里面添加 d:\gdb 就可以了。路径之间用分号隔开。

然后你启动一个cmd 就可以运行gdb了。

我把修改PATH 的资料发到你消息里面。


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/tougao/7775391.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-09
下一篇 2023-04-09

发表评论

登录后才能评论

评论列表(0条)

保存