gdb的使用总结

本文详细介绍了如何使用gdb工具分析core文件,包括核心配置、启动gdb、查看栈帧、定位问题等步骤,适用于软件开发和调试场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

启动初始

gdb启动时默认从初始化文件中读取命令作些初始化工作,初始化文件顺序为

  1. system.gdbinit
  2. ~/.gdbinit
  3. ./.gdbinit

可以通过选项参数-nx或者-n设置不从初始化文件中作初始化工作

gdb启动时主要做了哪些事?

  1. 读取--with-system-gdbinit初始化文件,执行文件中的命令
  2. 读取主目录下的gdbinit文件,执行文件中的命令
  3. 执行-iex或者-ix指定的命令或者命令文件中的命令
  4. 处理命令行参数
  5. 当set auto-load local-gdbinit开启时,读取当前工作目录下的gdbini文件,执行文件中的命令
  6. 如果命令行指定的调试的进程或者进程id,则加载为程序提供的自动加载脚本
  7. 执行-ex或者-x指定的命令
  8. 读取历史文件中的命令历史

文件选择

主要包含符号文件 ,二进制文件 ,core文件。在没有指定选项情况下, 默认将第一个参数作为二进制文件,第二个参数作为core文件,如果第二个参数是以数字开始,则作为进程号,gdb调试附加到对应进程,如果失败,则当作core文件处理

符号文件使用选项-symbols file或者-s file

二进制文件使用选项-exec file或者-e file或者-se file(符号文件与二进制文件二合一)

core文件使用选项-core file或者-c file

命令文件使用选项-command file或者-x file

在加载执行gdbinit文件后执行的初始化命令文件选项用-init-command file或者-ix file

执行命令选项

选项有两种,其中-init-eval-command是在加载完gdbinit文件后才执行

  • -eval-command command或者-ex command
  • -init-eval-command command或者-iex command

core文件 

设置ulimit -c unlimited

echo "core" > /proc/sys/kernel/core_pattern

在程序core时,需要用到gdb分析问题出在哪里

1、gdb --core=core文件  程序名

2、bt(显示所有栈桢)

3、在知道问题出在哪个栈帧后,用up num向上进num个栈帧

4、用p来输出变量信息

栈帧图

设置断点

1、filename:linenum

2、function

3、function:label

4、filename:function

gdb多线程调试的基本命令

1、info threads   显示当前可调试的线程,每个线程都有一个id

2、thread id       切换当前调试的线程为指定id的线程

3、set scheduler-locking on / off     设置当前线程执行,不会被其它线程干扰

查看数据

查看内存数据可以使用p或者x命令

x命令格式为

x/nfu addr

其中n表示查看多少个,f表示查看格式,u表示单元,支持b(字节),h(两字节),w(四字节),g(8字节)

查看格式

x:十六进制形式

d:十进制形式

u:无符号十进制形式

o:六进制形式

t:二进制形式

a:地址形式

c:字符形式

f:浮点数形式

s:作为字符串

z:与x相似,但是包含前导0

r:原始形式

i:主要针对代码,如$pc或者对应代码段的地址

文件各段地址分布情况 

显示数据段,代码段以及地址范围情况

使用info files或者info target

查看汇编代码

使用disassemble或者简写形式disas

支持的选项有,其中m,s参数表示混合形式,源代码+汇编形式,r表示以16进制原始形式

  • /m
  • /s
  • /r

参数形式支持,开始结束地址形式和开始地址+指定长度。参数可以是表达式,如0x32c4, &main+10或者$pc-8

  • start,end
  • start,+length

设置搜索源文件或者脚本文件路径

使用选项-directory directory或者-d directory

执行shell脚本

使用shell command-string或者!command-string

编译脚本使用make make-args

帮助命令

查看总体帮助信息

使用help或者简写形式h查找帮助类

查看子类帮助

使用help 子类信息,如help status

查看具体的命令帮助信息

使用help command

info和show的差异

info用于显示程序的状态,而show用于显示gdb的状态

查看符号表

配置

设置/查看大小写敏感使用

set case-sensitive on
set case-sensitive off
set case-sensitive auto
show case-sensitive

配置/查看输出类的方法名

set print type methods
set print type methods on
set print type methods off
show print type methods

配置/查看类中的类型定义

set print type typedefs 
set print type typedefs on
set print type typedefs off
show print type typedefs

查看符号

查看符号存放的地址

info address symbol

查看地址对应的符号

info symbol addr

解构符号名

demangle [-l language] [--] name

查看变量类型

whatis/ptype [/flags] [arg]

当arg没有提供时,则输出$即值历史中的最后一个值的数据类型

如果arg是变量或者表达式,则输出代码中的字面类型。如果类型是typedef定义的类型,whatis不会输出typedef背后的数据类型。如果 arg 是使用 typedef 定义的类型名称,则 whatis 仅展开该 typedef 的一个级别

flags支持的参数有

  • r:显示原始类型
  • m:不会打印类中定义的方法
  • M:打印类中定义的方法
  • t:不打印类中定义的typedefs类型
  • T:打印类中定义的typedefs类型

ptype与whatis相比,会输出更加详细的信息,同时对于typedef类型没有层级限制

查看类型信息

info types regexp
info types

在没有参数情况下,会输出程序的所有类型定义。在指定参数情况下,会输出类型名字中包含regexp的类型,其与whatis一样,不会输出详细信息,会列出类型定义所在的所有源文件

类型打印机

info type-printers
enable type-printers name...
disable type-printers name...

查看某位置的局部变量

info scope location

查看源文件

info source
info sources

info source查看当前执行点源文件的信息

info sources查看当前程序所有源文件

查看函数

info functions
info functions regexp

查看变量

info variables
info variables regexp

查看函数外定义的变量,不包含局部变量。查看虚函数表使用

info variables vtable //查看所有的虚函数表
info variables vtable.*class//查看class的虚函数表

查看类

info classes
info classes regexp

用在ojbect-c 

查看选择器

info selectors
info selectors regexp

用在ojbect-c

配置模糊类型解析

set opaque-type-resolution on
set opaque-type-resolution off
show opaque-type-resolution

配置打印符号加载 

set print symbol-loading
set print symbol-loading full
set print symbol-loading brief
set print symbol-loading off
show print symbol-loading

输出符号信息到指定文件 

maint print symbols filename
maint print psymbols filename
maint print msymbols filename

其中 psymbols表示部分符号,msymbols表示最小符号

查找符号信息

maint info symbols [regexp]
maint info psymbols [regexp]

符号缓存

maint set symbol-cache-size size
maint show symbol-cache-size
maint print symbol-cache
maint print symbol-cache-statistics
maint flush-symbol-cache

查看源文件 

使用list查找源文件,默认显示10行,可以通过set listsize来设置list的显示行数

list linenum //显示当前源文件以行号linenum为中心的代码
list function //显示以函数名function 为中心的代码
list  //如果上次命令为list,此次打印紧跟上次打印的最后一行
list - //打印上次的

set listsize count //count为显示的行数
set listsize unlimited 
show listsize

list支持的参数形式有

  • list location
  • list first,last
  • list ,last 表示显示直到last行
  • list first, 表示显示从first开始
  • list + 表示显示上次之后的
  • list - 表示显示上次之前的
  • list

location支持的形式有

  • linenum 行号
  • -offset/+offset 当前行偏移前或者偏移后
  • filename:linenum 文件的哪一行
  • function 表示从函数体开始
  • function:label 表示从函数中的某标签开始
  • filename:function 表示从某文件的某函数开始
  • label 表示当前选择栈帧的某标签开始
### GNU Debugger (GDB) 使用教程 #### 编译带有调试信息的程序 为了使 GDB 正常工作,在编译 C 或者 C++ 程序时应当加入 `-g` 参数来包含调试信息。对于一个名为 `a.cpp` 的源文件,可以使用如下命令进行编译: ```bash g++ a.cpp -o a -g ``` 这将在当前目录下创建一个可执行文件 `a` 并附带必要的调试数据[^3]。 #### 启动 GDB 调试环境 完成上述操作后,可以通过指定生成的目标文件启动 GDB: ```bash gdb ./a ``` 此时即进入了交互式的 GDB 控制台界面。 #### 基础命令概览 在 GDB 中有多个基础命令可以帮助开发者定位并解决问题,下面列举了一些常用的指令及其功能简介: - **run**: 开始运行被调试的应用程序;如果已经设置断点,则会在遇到第一个断点处暂停。 - **breakpoint** / **b**: 设置断点,参数可以是指定函数名或某行代码的位置。 - **continue** / **c**: 继续执行直到下一个断点位置。 - **step** / **s**: 单步执行,进入子过程内部继续单步步过每一句语句。 - **next** / **n**: 类似于 step, 不同之处在于 next 只会跨过整个函数调用而不会深入到其内部逻辑中去。 - **print** / **p**: 显示变量的具体数值或其他表达式的计算结果。 - **backtrace** / **bt**: 展示完整的栈回溯路径以便理解错误发生前后的流程走向。 - **quit** / **q**: 结束本次调试会话退出 GDB[^1][^2]. #### 解决常见问题的方法 当面对某些特定类型的异常情况时,这里提供几种可能有效的解决方案: ##### 断点失效 确保所设断点位于有效范围内——比如实际存在的函数体内而非声明部分,并且该区域确实会被执行流触及。另外注意区分大小写字母以及确认拼写无误。 ##### 查看内存泄漏 利用 Valgrind 工具配合 GDB 来检测潜在的动态分配对象未释放等问题。先通过 valgrind 执行一遍测试案例获取报告提示后再回到 GDB 中精确定位具体哪一部分存在问题。 ##### 处理多线程应用中的死锁现象 借助 Thread Analyzer 插件辅助分析各线程之间的同步关系图谱从而找出造成阻塞的关键环节所在。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

kgduu

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

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

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

打赏作者

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

抵扣说明:

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

余额充值