初识gdb调试器

Gdb是Linux下一款功能强大的c/c++程序调试工具

一般来说,gdb主要提供以下功能

1.      设置断点(断点可以是条件表达式),使程序在制定的代码上暂停执行,便于观察

2.      单步执行程序,便于调试。

3.      查看程序中变量值得变换。

4.      动态改变程序的执行环境

5.      分析崩溃程序产生的core文件

gdb常用命令

命令

含义描述

file

装入想要调试的可执行文件

run

执行当前被调试的程序

kill

终止正在调试的程序

step

执行 一行源代码而且进入函数内部

next

执行一行源代码但不进入函数内部

backtrace

回溯跟踪

fram n

定位到发生错误的代码段,n为backtrace命令输出结果中的行号

break

在代码里设置断点,这将使程序执行到这里时被挂起

print

打印表达式或变量的值,或打印内存中某个变量开始的一段连续区域的值,还用来对变量进行赋值

display

设置自动显示的表达式或变量,当程序挺住或在单步跟踪时,这些变量会自动显示其当前值

list

列出产生可执行文件的源代码的一部分

 

 

gdb调试初步

程序代码:

 

Run

通过run命令让程序开始在gdb的监控下运行

通过上图可知具体发生问题的地方是在调用_IO_vfscanf_internal(),通过gdb提供的回溯跟踪命令backtrace得到更有价值的信息。

使用frame n命令可以定位到发生错误的代码段,该命令后面跟着的数值可以在backtrace命令输出结果中的行首找到。

gdb的使用详解

使用断点

断点指出了gdb将要在该点处中断程序的运行,从而便于程序员单步跟踪代码。

break(简称b)

命令

含义描述

break <function>

在进入指定函数时停住,C++中可以使用class::function或function(type,type)格式来指定函数名

break <linenum>

在指定行号停住

break +offset

在当前行号的前面的offset行停住。offset为自然数

break -offset

在当前行号的后面的offset行停住

break filename:linenum

在源文件filename的linenum行停住

break filename:function

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

break *address

在程序运行的内存地址处停住

break

该命令没有参数时,表示在下一条指令处停住

break ..if<condition>

Condition表示条件,在条件成立时停住。比如在循环体中,可以设置break if i=100,

表示当i为100时停住程序

gdb常用命令的参数

命令

含义描述

<linenum>

行号

<function>

函数名

<+offset>

当前行号的正偏移量

<-offset>

当前行号的负偏移量

<filename:linenum>

某个文件的某一行

<filename:function>

某个文件的某个子函数

<*address>

程序运行时的语句在内存中的地址

将断点定在main函数

使用run(简称r)命令开始执行程序

使用单步调试命令step(简称s)来跟踪程序,它一次只执行程序中的一行代码。

查看运行时数据

print命令

当使用gdb的print命令查看程序运行时的数据时,每一个print都会被gdb记录下来。Gdb会以$1,$2,$3,…这样的方式为每一个print命令编上号。

要注意print命令的表达式中两个具有特殊意义的符号,$和$$.$表示给定序号的前一个序号,而$$表示给定序号的向前两个的序号,如果不给定序号,gdb将默认当前序号为给定序号

 

Print的输出格式

符号

含义

x

按十六进制格式显示变量

d

按十进制显示变量

u

按十六进制格式显示无符号整形

o

按八进制显示变量

t

按二进制显示变量

a

按十六进制显示变量

c

按字符格式显示变量

f

按浮点数格式显示变量

自动显示命令display

可以设置一些自动显示的变量,当程序挺住使,或是在单步跟踪时,这些变量会自动显示。

display <expr>

display/<fmt> <expr>

display/<fmt> <addr>

expr是一个表达式,fmt表示显示的格式,addr表示内存地址。

display/I $pc

$pc是gdb的环境变量,表示指令的地址,/i则表示输出格式为机器指令码。

Display相关命令

命令

含义藐视

undisplay <dnums…>

delete display<dnums…>

删除自动显示,dnums为已设置好了的自动显示编号。如果要同时删除几个编号,可以用空格分隔:如果要删除一个范围内的编号,可以用减号表示

disable display<dnums..>

enable display<dnums…>

不删除自动显示的设置,而只是让其失效或回复

Info display

查看display设置的自动显示的信息。

查看内存

可以使用examine命令(简称x)来查看内存地址中的值

x/<n/f/u> <addr>

n表示显示内存的长度

f表示显示的格式

u表示从当前地址往后请求的字节数,如不指定的话,gdb默认是4个bytes

gdb环境变量

set $变量名

查看环境变量

Show convenience

查看寄存器

当前运行的指令地址(IP),程序的当前堆栈地址(SP)

命令

含义藐视

info registers

查看寄存器的情况

info all-registers

查看所有寄存器的情况

info registers<regname..>

查看所指定的寄存器的情况,rename表示寄存器名,多个寄存器之间用逗号隔开

查看源程序

List命令

命令

含义描述

list <linenum>

显示程序第linenum行周围的源程序

list <function>

显示名为function的函数的源程序

list

显示当前行后面的源程序

list -

显示当前行前面的源程序。一般是显示当前行的上5行和下5行

list +

向后显示源代码

set listsize

查看当前listsize的设置

show listsize

设置一次显示源程序的行数

list <first>,<last>

显示从first行到last行之间的源代码

List ,<last>

显示从当前行到last行之间的源代码

源代码的内存

可以使用info line命令来查看源代码在内存中的地址。

disassemble可以查看源程序当前执行时的机器码,这个命令会把当前内存中的指令dump出来。

Disassemble是一个非常有用的命令,对于那些熟悉汇编语言的c程序员,他们在编写大型程序的时候,往往要考虑系统硬件内存资源的分配等问题,这时候利用反汇编来查看当前程序执行的机器码,对于程序的检错纠错是很有帮助的。

 

改变程序的执行

一旦使用gdb挂上被调试程序,当程序执行起来后,可以根据自己的调试思路来动态地在gdb中更改当前被调试程序的运行路线或其变量的值。

 

修改变量的值

print命令还有一个功能是修改被调试程序中运行时的变量值

print x=8

跳转执行

一般来说,被调试程序会按照程序代码的运行顺序依次执行,gdb提供了乱序执行的功能。Gdb可以修改程序的执行顺序,可以让程序执行随意跳跃。

jump <linespec>

指定下一条语句的运行点。<linespec>可以是文件的行号,可以是file:line格式,可以是+num这种偏移量格式。

jump <address>

产生信号量

使用signal命令可以产生一个信号量给被调试的程序。如中断信号CTRL+C。

signal <signal>

linux的系统信号量通常从1-15.

强制函数返回

如果调试断点在某个函数中,还有语句没有执行完,可以使用return命令强制函数忽略还没有执行的语句并返回。

return

return <expression>

使用return命令取消当前函数的执行,并立即返回。如果指定了<expression>,那么该表达式会被当做函数的返回值。

强制调用函数

强制调用函数使用call命令。

call <expr>

表达式中也可以是函数,已达到强制调用函数的目的,显示函数的返回值,如果返回值是void,那么就不显示。

Gdb的语言环境命令

命令

含义描述

show language

查看当前的语言环境

info frame

查看当前函数的程序语言

info source

查看当前文件的程序语言

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yiluohan0307

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值