0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

对GDB命令脚本做一个粗浅的介绍

嵌入式与Linux那些事 来源:嵌入式与Linux那些事 2023-02-06 11:41 次阅读

在shell下敲gdb命令即可启动gdb,启动后会显示下述信息,出现gdb提示符。

➜examplegdb
GNUgdb(Ubuntu8.1.1-0ubuntu1)8.1.1
Copyright(C)2018FreeSoftwareFoundation,Inc.
LicenseGPLv3+:GNUGPLversion3orlater
Thisisfreesoftware:youarefreetochangeandredistributeit.
ThereisNOWARRANTY,totheextentpermittedbylaw.Type"showcopying"
and"showwarranty"fordetails.
ThisGDBwasconfiguredas"x86_64-linux-gnu".
Type"showconfiguration"forconfigurationdetails.
Forbugreportinginstructions,pleasesee:
.
FindtheGDBmanualandotherdocumentationresourcesonlineat:
.
Forhelp,type"help".
Type"aproposword"tosearchforcommandsrelatedto"word".
(gdb)

测试代码

#include
intminus(inta,intb){
printf("Inminus():
");
intc=a-b;
returnc;
}
intsum(inta,intb){
printf("Insum():
");
intc=a+b;
returnc;
}
voidprint(intxx,int*xxptr){
printf("Inprint():
");
printf("xxis%dandisstoredat%p.
",xx,&xx);
printf("ptrpointsto%pwhichholds%d.
",xxptr,*xxptr);
intc=sum(2,3);
intd=minus(3,2);
}

intmain(void){
intx=10;

int*ptr=&x;
printf("Inmain():
");
printf("xis%dandisstoredat%p.
",x,&x);
printf("ptrpointsto%pwhichholds%d.
",ptr,*ptr);

print(x,ptr);
return0;
}

设置断点

可以在函数名和行号等上设置断点。程序运行后,到达断点就会自动暂停运行。

此时可以查看该时刻的变量值、显示栈帧、重新设置断点或重新运行等。断点命令(break)可以简写为b。

格式

break断点

举例

(gdb)bmain
Breakpoint1at0x758:filegdb_example.c,line9.

格式

break函数名
break行号
break文件名:行号
break文件名:函数名
break+偏移量
break-偏移量
break*地址

举例

(gdb)bprint
Breakpoint2at0x709:filegdb_example.c,line4.
(gdb)bgdb_example.c:5
Breakpoint3at0x715:filegdb_example.c,line5.
(gdb)b+3
Note:breakpoint2alsosetatpc0x709.
Breakpoint4at0x709:filegdb_example.c,line4.
(gdb)b*0x709
Note:breakpoints2and4alsosetatpc0x709.
Breakpoint5at0x709:filegdb_example.c,line4.
(gdb)

上面的例子分别对print函数,gdb_example.c第5行,现在暂停位置往后第3行,地址0x709设置断点。

设置好的断点可以通过info break 确认

(gdb)infobreak
NumTypeDispEnbAddressWhat
1breakpointkeepy0x0000000000000758inmainatgdb_example.c:9
2breakpointkeepy0x0000000000000709inprintatgdb_example.c:4
3breakpointkeepy0x0000000000000715inprintatgdb_example.c:5
4breakpointkeepy0x0000000000000709inprintatgdb_example.c:4
5breakpointkeepy0x0000000000000709inprintatgdb_example.c:4

显示栈帧

backtrace命令可以在遇到断点而暂停执行时显示栈帧。该命令简写为bt。此外, backtrace的别名还有where和info stack(简写为info s)。

backtrace
bt

显示所有栈帧

backtraceN
btN

只显示开头N个栈帧

backtrace-N
bt-N

只显示最后N个栈帧

backtracefull
btfull
backtracefullN
btfullN
backtracefull-N
btfull-N

举例

(gdb)b4
Breakpoint1at0x714:filegdb_example.c,line4.
(gdb)r
Startingprogram:/home/zhongyi/code/example/gdb_example
Inmain():
xis10andisstoredat0x7fffffffe2fc.
ptrpointsto0x7fffffffe2fcwhichholds10.
Inprint():
xxis10andisstoredat0x7fffffffe2cc.
ptrpointsto0x7fffffffe2fcwhichholds10.
Insum():
Inminus():

Breakpoint1,minus(a=3,b=2)atgdb_example.c:4
4intc=a-b;
#显示栈帧
(gdb)bt
#0minus(a=3,b=2)atgdb_example.c:4
#10x00005555555547c0inprint(xx=10,xxptr=0x7fffffffe2fc)atgdb_example.c:17
#20x0000555555554841inmain()atgdb_example.c:28
#只显示前2个栈帧
(gdb)bt2
#0minus(a=3,b=2)atgdb_example.c:4
#10x00005555555547c0inprint(xx=10,xxptr=0x7fffffffe2fc)atgdb_example.c:17
(Morestackframesfollow...)
#从外向内显示2个栈帧,及其局部变量
(gdb)btfull-2
#10x00005555555547c0inprint(xx=10,xxptr=0x7fffffffe2fc)atgdb_example.c:17
c=5
d=21845
#20x0000555555554841inmain()atgdb_example.c:28
x=10
ptr=0x7fffffffe2fc
(gdb)

显示栈帧后,就可以确认程序在何处停止,及程序的调用路径。

显示变量

格式

print变量

举例

(gdb)px
$1=10
(gdb)pptr
$2=(int*)0x7fffffffe2fc
(gdb)

显示寄存器

举例

(gdb)inforeg
rax0xc12
rbx0x00
rcx0x7ffff7af2104140737348837636
rdx0x7ffff7dcf8c0140737351841984
rsi0x55555575626093824994337376
rdi0x11
rbp0x7fffffffe3100x7fffffffe310
rsp0x7fffffffe2f00x7fffffffe2f0
r80x7ffff7fe14c0140737354011840
r90x00
r100x00
r110x246582
r120x5555555545f093824992232944
r130x7fffffffe3f0140737488348144
r140x00
r150x00
rip0x5555555548410x555555554841
eflags0x202[IF]
cs0x3351
ss0x2b43
ds0x00
es0x00
fs0x00
gs0x00

寄存器前加$,可以显示寄存器的内容。

(gdb)p$rdi
$7=1
(gdb)p$rax
$8=12
(gdb)

显示寄存器可以用以下格式

p/格式 变量

格式 说明
x 显示为16进制数
d 显示为十进制数
u 显示为无符号十进制数
o 显示为八进制数
t 显示为二进制数
a 地址
c 显示为ascii
f 浮点小数
s 显示为字符串
i 显示为机器语言(仅在显示内存的x命令中可用)

显示内存

x命令可以显示内存的内容

格式

x/格式地址

举例

(gdb)x$r12
0x5555555545f0<_start>:xor%ebp,%ebp
(gdb)x$r8
0x7ffff7fe14c0:rclb$0xf7,(%rsi,%rdi,8)
(gdb)

x/i 可以显示汇编指令。一般用x命令时,格式为x/NFU ADDR。此处ADDR为希望显示的地址,N为重复次数。F为前面讲过的格式,u代表的单位如下。

单位 说明
b 字节
h 半字(2字节)
w 字(4字节)
g 双字(8字节)

下面显示从rsp开始的10条指令。

(gdb)x/10i$rsp
0x7fffffffe2f0:(bad)
0x7fffffffe2f1:rex.Wpush%rbp
0x7fffffffe2f3:push%rbp
0x7fffffffe2f4:push%rbp
0x7fffffffe2f5:push%rbp
0x7fffffffe2f6:add%al,(%rax)
0x7fffffffe2f8:lockrex.RBpush%r13
0x7fffffffe2fb:push%rbp
0x7fffffffe2fc:or(%rax),%al
0x7fffffffe2fe:add%al,(%rax)

显示反汇编

格式

disassemble
disassemble程序计数器
disassemble开始地址结束地址

格式1为反汇编当前整个函数,2为反汇编程序计数器所在函数的整个函数。3为反汇编从开始地址到结束地址的部分。

(gdb)disassemble
Dumpofassemblercodeforfunctionsum:
0x0000555555554722<+0>:push%rbp
0x0000555555554723<+1>:mov%rsp,%rbp
0x0000555555554726<+4>:sub$0x20,%rsp
0x000055555555472a<+8>:mov%edi,-0x14(%rbp)
0x000055555555472d<+11>:mov%esi,-0x18(%rbp)
0x0000555555554730<+14>:lea0x1bd(%rip),%rdi#0x5555555548f4
0x0000555555554737<+21>:callq0x5555555545b0
=>0x000055555555473c<+26>:mov-0x14(%rbp),%edx
0x000055555555473f<+29>:mov-0x18(%rbp),%eax
0x0000555555554742<+32>:add%edx,%eax
0x0000555555554744<+34>:mov%eax,-0x4(%rbp)
0x0000555555554747<+37>:mov-0x4(%rbp),%eax
0x000055555555474a<+40>:leaveq
0x000055555555474b<+41>:retq
Endofassemblerdump.

单步执行

执行源代码中的一行:next
进入函数内部执行:step
逐条执行汇编指令:nexti,stepi

继续运行

格式

continue
continue次数

指定次数可以忽略断点,例如,continue 5 则5次遇到断点不会停止,第6次遇到断点才会停止。

监视点

格式

watch<表达式>

<表达式>发生变化时暂停运行,<表达式>意思是常量或变量

awatch<表达式>

<表达式>被访问,改变时暂停运行

rwatch<表达式>

<表达式>被访问时暂停运行

举例

(gdb)watchc
Hardwarewatchpoint2:c
(gdb)c
Continuing.

Hardwarewatchpoint2:c

Oldvalue=21845
Newvalue=5
sum(a=2,b=3)atgdb_example.c:10
10returnc;
(gdb)

格式

删除断点和监视点

delete<编号>

<编号>指的是断点或监视点

举例

(gdb)infob
NumTypeDispEnbAddressWhat
1breakpointkeepy0x000055555555473cinsumatgdb_example.c:9
breakpointalreadyhit1time
2hwwatchpointkeepyc
breakpointalreadyhit1time
(gdb)delete2
(gdb)infob
NumTypeDispEnbAddressWhat
1breakpointkeepy0x000055555555473cinsumatgdb_example.c:9
breakpointalreadyhit1time
(gdb)

改变变量的值

格式

setvariable<变量>=<表达式>

举例

(gdb)pc
$1=5
(gdb)setvariablec=0
(gdb)pc
$2=0
(gdb)

生成内核转储文件

(gdb)generate-core-file
warning:Memoryreadfailedforcorefilesection,4096bytesat0xffffffffff600000.
Savedcorefilecore.2380

有了内核转储文件,即使退出了GDB也能查看生成转储文件时的运行历史。

gcore'pidofgdb_example'

该命令无需停止正在运行的程序,可以直接从命令行直接生成转储文件。当需要在其他机器上单独分析问题原因时,或者是分析客户现场问题时十分有用。

条件断点

break断点if条件

如果条件为真,则暂停运行

condition断点编号
condition断点编号条件

第一条指令删除指定断点编号的触发条件,第二条指令给断点添加触发条件

反复执行

ignore断点编号次数

在编号指定的断点,监视点忽略指定的次数

continue与ignore一样,也可以指定次数,达到指定次数前,执行到断点时不暂停。

continue次数
step次数
stepi次数
next次数
nexti次数
finish
until
until地址

finish 执行完当前函数后暂停,until命令执行完当前函数等代码块后暂停,常用于跳出循环。、

删除断点或禁用断点

clear
clear函数名
clear行号
clear文件名:行号
clear文件名:函数名
delete[breakpoints]断点编号

clear 用于删除已定义的断点

disable[breakpoints]
disable[breakpoints]断点编号
disabledisplay显示编号
disablemem内存区域

disable 临时禁用断点。第3种格式禁用display命令定义的自动显示,第4种格式禁用mem命令定义的内存区域。

enable
enable[breakpoints]断点编号
enable[breakpoints]once断点编号
enable[breakpoints]delete断点编号
enabledisabledisplay显示编号
enablemem内存区域

once 使指定的断点只启用一次。delete表示在运行暂停后删除断点。

断点命令

格式

commands断点编号
命令
...
end

程序在指定的断点处暂停,就会自动执行命令。

举例

(gdb)b17
Breakpoint3at0x5555555547b1:filegdb_example.c,line17.
(gdb)command3
Typecommandsforbreakpoint(s)3,oneperline.
Endwithalinesayingjust"end".
>pc
>end
(gdb)r
Startingprogram:/home/zhongyi/code/example/gdb_example-e'p1'
Inmain():
xis10andisstoredat0x7fffffffe2ec.
ptrpointsto0x7fffffffe2ecwhichholds10.
Inprint():
xxis10andisstoredat0x7fffffffe2bc.
ptrpointsto0x7fffffffe2ecwhichholds10.
Insum():

Breakpoint3,print(xx=10,xxptr=0x7fffffffe2ec)atgdb_example.c:17
17intd=minus(3,2);
$1=5

上例表示在17行暂停后打印c的值。

与前面的条件断点组合使用,可以在断点暂停时执行复杂的动作。

举例

break17ifc==5
commands
silent
printf“xis%d
”,x
cont
end

常用命令及其缩略形式

命令 简写形式 说明
backtrace bt/where 显示backtrace
break 设备断点
continue c/cont 继续运行
delete d 删除断点
finish 运行到函数结束
info breakpoints 显示断点信息
next n 执行下一行
print p 显示表达式
run r 运行程序
step s 一次执行一行,包括函数内部
x 显示内存内容
until u 执行到指定行
directory dir 插入目录
disable dis 禁用断点
down do 在当前栈帧中选择要显示的栈帧
edit e 编辑文件或函数
frame f 选择要显示的栈帧
forward-search fo 向前搜索
generate-core-file gcore 生成内核转储
help h 显示帮助文档
info i 显示信息
list l 显示函数行
nexti ni 执行下一行(以汇编代码为单位)
print-object po 显示目标信息
sharedlibrary share 加载共享库的符号
stepi si 执行下一行

值的历史

通过print命令显示过的值会记录在内部的值历史中,这些值可以在其他表达式中使用。

举例

(gdb)b16
Breakpoint1at0x79f:filegdb_example.c,line16.
(gdb)b17
Breakpoint2at0x7b1:filegdb_example.c,line17.
(gdb)b29
Breakpoint3at0x841:filegdb_example.c,line29.
(gdb)r
Startingprogram:/home/zhongyi/code/example/gdb_example
Inmain():
xis10andisstoredat0x7fffffffe2fc.
ptrpointsto0x7fffffffe2fcwhichholds10.
Inprint():
xxis10andisstoredat0x7fffffffe2cc.
ptrpointsto0x7fffffffe2fcwhichholds10.

Breakpoint1,print(xx=10,xxptr=0x7fffffffe2fc)atgdb_example.c:16
16intc=sum(2,3);
(gdb)pc
$1=1431651824
(gdb)c
Continuing.
Insum():

Breakpoint2,print(xx=10,xxptr=0x7fffffffe2fc)atgdb_example.c:17
17intd=minus(3,2);
(gdb)pc
$2=5
(gdb)c
Continuing.
Inminus():

Breakpoint3,main()atgdb_example.c:29
29return0;

最后的值可以使用$ 访问。

通过show values 可以显示历史中的最后10个值

举例

(gdb)showvalues
$1=1431651824
$2=5
$3=10
$4=10
(gdb)

值的历史的访问变量和说明

变量 说明
$ 值历史中的最后一个值
$n 值历史的第n个值
$$ 值历史的倒数第二个值
$$n 值历史的倒数第n个值
$_ x命令显示过的最后的地址
$__ x命令显示过的最后的地址的值
$_exitcode 调试中的程序的返回代码
$bpnum 最后设置的断点的编号

可以随意定义变量。变量以$开头,有英文和数字组成。

举例

(gdb)set$i=0
(gdb)p$i
$5=0
(gdb)

命令历史

可以把命令保存在文件中,保存命令历史后,就可以在其他调试会话中使用。默认命令历史文件位于./.gdb_history

sethistoryexpansion
showhistoryexpansion

可以使用csh风格的!字符

sethistoryfilename文件名
showhistoryfilename

可将命令历史保存到文件中,可以通过环境变量GDBHISTFILE改变默认文件。

sethistorysave
showhistorysave

启用命令历史保存到文件和恢复的功能。

sethistorysize数字
showhistorysize

设置保存到命令历史中的命令数量,默认为256。

初始化文件(.gdbinit)

Linux下gdb初始化文件为.gdbinit。如果存在.gdbinit文件,GDB在启动之前将其作为命令文件运行。

顺序如下:

$HOME/.gdbinit

运行命令行选项

./.gdbinit

加载通过-x选项给出的命令文件

命令定义

用define可以自定义命令,用document可以给自定义的命令加说明,利用help 命令名可以查看定义的命令。

define格式:

define命令名
命令
…………
end

document格式:

document命令名
说明
end

help格式:

help命令名

以下示例定义了名为li的命令。

举例

(gdb)defineli
Typecommandsfordefinitionof"li".
Endwithalinesayingjust"end".
>x/10i$rbp
>end
(gdb)documentli
Typedocumentationfor"li".
Endwithalinesayingjust"end".
>listmachineinstruction
>end
(gdb)li
0x7fffffffe310:(bad)
0x7fffffffe311:rex.Wpush%rbp
0x7fffffffe313:push%rbp
0x7fffffffe314:push%rbp
0x7fffffffe315:push%rbp
0x7fffffffe316:add%al,(%rax)
0x7fffffffe318:xchg%edi,(%rax,%riz,4)
0x7fffffffe31b:idiv%edi
0x7fffffffe31d:jg0x7fffffffe31f
0x7fffffffe31f:add%al,(%rcx)
(gdb)helpli
listmachineinstruction

还可以把各种设置写在文件中,运行调试器时读取这些文件。

source文件名

总结

本文只是对gdb命令脚本做了一个粗浅的介绍,旨在起到抛砖引玉的效果。





审核编辑:刘清

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 寄存器
    +关注

    关注

    30

    文章

    5186

    浏览量

    118368
  • 计数器
    +关注

    关注

    32

    文章

    2219

    浏览量

    93563
  • Shell
    +关注

    关注

    1

    文章

    358

    浏览量

    22997
  • GDB调试
    +关注

    关注

    0

    文章

    24

    浏览量

    1411

原文标题:【调试】GDB使用总结

文章出处:【微信号:嵌入式与Linux那些事,微信公众号:嵌入式与Linux那些事】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    什么是GDBGDB的基本功能和命令总结

    GDB是嵌入式软件工程师调试用的比较多的一种工具,今天就来简单分享一下GDB相关命令
    的头像 发表于 11-07 09:15 2372次阅读

    进入gdb后可使用的gdb命令

    gdb-optionsexecutable-file 进入gdb后可使用的gdb命令: File:装入想要调试的可执行文件 Cd:改变工作目录。 Pwd:返回当前工作目录
    发表于 07-03 05:26

    linux 3 - gdb的安装和使用介绍

    是7.2版的,好的,那么接下来就是使用GDB了 5.我们可以在linux下写简单的程序来测试下 我们来使用gdb编译下啊 6.使用
    发表于 07-03 13:27

    GDB定义命令无响应

    GDB定义命令无响应以上来自于谷歌翻译以下为原文 GDB define command not responsive
    发表于 04-10 10:02

    gdb基本命令怎么使用?

    gdb基本命令怎么使用?
    发表于 12-24 06:32

    GDB的常用命令是什么?

    GDB的常用命令是什么?GDB的使用条件是什么?GDB如何调试?
    发表于 12-24 07:08

    GDB调试命令手册

    GDB调试命令手册,感兴趣的可以下载看看。
    发表于 11-05 16:36 9次下载

    GDB调试命令总结

    gdb attach pid //用gdb调试已经开始运行的程序,指定pid即可2.调试命令(1)执行命令模式-batch选项。比如:打印$pid进程所有线程的堆栈并退出。
    发表于 04-02 14:31 1046次阅读

    实例演示GDB的使用

    GDB简介 GDB(GNU Debugger)是一个强大的命令行调试工具。一般的,在Windows下进行开发,很少操控命令行调试,调试器大多与编译器都集成在IDE里了。 当然,在Win
    的头像 发表于 10-19 09:58 2451次阅读
    实例演示<b class='flag-5'>GDB</b>的使用

    Linux系统命令及shell脚本实践指南

    Linux系统命令及shell脚本实践指南资料下载。
    发表于 06-01 14:47 27次下载

    Linux命令行与shell脚本编写

    Linux命令行与shell脚本编写
    发表于 01-11 16:50 4次下载

    shell脚本本身自带的命令详解

    除了以文件形式保存在/usr/bin下面的命令,shell脚本中还可以使用shell本身自带的命令,即内置命令
    的头像 发表于 05-23 09:32 713次阅读
    shell<b class='flag-5'>脚本</b>本身自带的<b class='flag-5'>命令</b>详解

    shell脚本基本命令

    Shell脚本是一种可执行文件,它包含了一组用某种特定语言编写的命令,这些命令可以被解释器(如bash)执行。以下是一些常见的shell脚本基本命令
    的头像 发表于 11-08 10:08 841次阅读

    脚本调试工具有哪些?脚本调试工具怎么用?

    脚本调试是软件开发过程中非常重要的一环,它能帮助开发者快速定位并解决代码中的错误。大多数编程语言都提供了各种各样的脚本调试工具,本文将介绍一些常见的脚本调试工具以及它们的基本使用方法。
    的头像 发表于 12-01 14:40 421次阅读

    如何使用linux下gdb来调试python程序

    中,我们将介绍如何在Linux中使用GDB来调试Python程序。 一、安装GDB和Python调试符号 在使用GDB调试Python程序之前,需要安装
    的头像 发表于 01-31 10:41 922次阅读