Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >gdb 调试笔记

gdb 调试笔记

原创
作者头像
De4dCr0w
修改于 2020-06-15 02:31:03
修改于 2020-06-15 02:31:03
95600
代码可运行
举报
运行总次数:0
代码可运行

一、环境安装

代码语言:txt
AI代码解释
复制
gdb 源码下载:https://ftp.gnu.org/gnu/gdb/
gdb 源码编译:
mkdir gdb‐build‐7.7
cd gdb‐build‐7.7
../gdb‐7.7/configure
或者 ‐‐target=i686‐elf ‐‐prefix=../gdb/install
make ‐j4
make install
安装后程序在/usr/local/bin
原先的程序在/usr/bin

二、自动化处理

(1)内核调试脚本
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
gdb \
‐ex "add‐auto‐load‐safe‐path $(pwd)" \
‐ex "file vmlinux" \
‐ex 'set arch i386:x86‐64:intel' \
‐ex 'target remote localhost:1234' \
‐ex 'continue' \
‐ex 'disconnect' \
‐ex 'set arch i386:x86‐64:intel' \
‐ex 'target remote localhost:1234'

三、断点相关

(1)条件断点
代码语言:txt
AI代码解释
复制
break write if $rsi == 2

(2)软件断点

代码语言:txt
AI代码解释
复制
beak 普通
tbreak 一次性
rbreak 接受正则表达式成批设置

原理:

  • 基于CPU的断点指令,如x86的INT 3(机器码0xCC)
  • 替换断点位置的指令
  • CPU执行到此时触发断点异常
  • 没有数量限制
(3)硬件断点
代码语言:txt
AI代码解释
复制
hbreak 普通
thbreak 一次性

原理:

  • 基于CPU的调试寄存器,如x86的DR0-DR7
  • 不需要修改程序代码,可以针对EEPROM上的代码位置
  • 有数量限制,x86上最多4个
(4)监视断点
代码语言:txt
AI代码解释
复制
监视表达式,值变化时中断
watch a*b + c/d
watch *(int *)0x12345678
watch *global_ptr

访问监视断点:
rwatch 表达式被读时断下
awatch 表达式被读或者被写时断下

(5)catch 断点:用于捕捉事件

代码语言:txt
AI代码解释
复制
事件包括如下:
exception [name]
exception unhandled
handlers [name]
assert
exec
syscall
syscall [name|number|group:groupname|g:groupname]
例:(gdb)catch syscall chroot
 (gdb) catch syscall group:process
 Catchpoint 1 (syscalls ’exit’ [1] ’fork’ [2] ’waitpid’ [7]
 ’execve’ [11] ’wait4’ [114] ’clone’ [120] ’vfork’ [190]
 ’exit_group’ [252] ’waitid’ [284] ’unshare’ [310])
 fork
 vfork
 load [regexp]
 unload [regexp]
 signal [signal...|'all']
 tcatch event 捕捉一次catch
(6)dprinf 遇到断点是打印信息
代码语言:txt
AI代码解释
复制
set dprintf‐style gdb/call/agent 设置用哪里的打印函数打印信息
set dprintf‐function fprintf 设置用什么函数打印
dprintf 25,"at line 25, glob=%d\n",glob
(7)trace 跟踪点

和break命令非常相似。其参数可以是源代码行,函数名或者目标程序的某个地址,trace

命令创建跟踪点,程序在此点上短暂中断,收集数据,然后程序继续往下执行。设置跟踪点

或者改变跟踪点命令直到下个tstart命令才会生效;因此,不能在跟踪会话过程中改变跟踪

点的属性。

代码语言:txt
AI代码解释
复制
delete tracepoint [num]
disable tracepoint [num]
enable tracepoint [num]
passcount [n [num]]
代码语言:txt
AI代码解释
复制
(gdb) passcount 5 2 // 跟踪点2在第5次执行时中止
(gdb) passcount 12 // 最近创建的跟踪点,在第12次执行时中断
(gdb) trace foo
(gdb) pass 3
(gdb) trace bar
(gdb) pass 2
(gdb) trace baz
(gdb) pass 1 // 在foo执行过3次,或者bar执行过2次,或者baz执行过1次时,中止跟踪

action num 执行到跟踪点要执行的命令,只有两种:collect, while‐stepping

例:

代码语言:txt
AI代码解释
复制
(gdb) trace foo
(gdb) actions
Enter actions for tracepoint 1, one per line:

> collect bar,baz
> collect $regs
> while‐stepping 12
	> collect $fp, $sp
	> end
 end
 collect expr1, expr2, …

 tstart 开始一次跟踪会话
 tstop 结束一次跟踪会话
 tstatus 显示当前跟踪数据收集的状态
(8)断下后执行命令

commands num(断点编号)在触发断点后执行commands,命令以end结束

用define 编写自定义的宏

(gdb) define br_info

Type commands for definition of "br_info".

End with a line saying just "end".

b $arg0

comm

i locals

i args

end

(gdb) br_info binary_search if target == 5

当if target == 5条件满足时,br_info binary_search会被执行。

br_info展开成为一系列命令,并用binary_search替换掉$arg0。

(9)管理断点
代码语言:txt
AI代码解释
复制
info/disable/delete break

保存断点到文件中
save breakpoints [filename] 保存现在的断点到文件中
source [filename] 恢复断点,将文件中的断点打一遍, watchpoints可能会失效

四、保存现场和回溯

(1)gdb 的快照保存
代码语言:txt
AI代码解释
复制
checkpoint: 生成当前状态的快照
info checkpoint:显示快照信息
restart checkpoint‐id:恢复到某个checkpoint
delete checkpoint checkpoint‐id:删除某个checkpoint

值得注意的是

  1. 保存快照的进程ID和之前不同
  2. 已经写入文件或者关闭设备这些操作不能撤回到原先的状态
  3. 恢复到快照后,会将快照覆盖,所以如果还想再调试一次,就要在恢复后重新建立一个快照。
  4. 快照是对原先进程的复制,所以地址相同,调试的时候可以对地址下断点,而不用管随机化
(2)逆向执行
代码语言:txt
AI代码解释
复制
首先启动record 功能,就可以进行命令回溯
reverse‐continue 缩写rc
reverse‐step /rs
reverse‐step /rsi
reverse‐next /rn
reverse‐nexti /rni
reverse‐finish
如果嫌麻烦可以设置执行方向
set exec‐direction reverse/forward 这样执行ni就是reverse‐nexti

record stop
(3)记录功能
代码语言:txt
AI代码解释
复制
record goto begin/start 跳转到记录的起始位置
record goto end 跳转到记录的结束位置
record goto n 跳到记录的第n条指令,默认可以记录20万条
record save filename 保存记录
record restore filename 恢复记录
(4)日志信息
代码语言:txt
AI代码解释
复制
set logging on 开启日志记录
set logging off 关闭日志记录
set logging file file 记录日志文件,默认是gdb.txt
set logging overwrite [on|off] 是否覆盖,默认是不覆盖,以追加的方式记录日志
show logging 显示日志设置
(5)栈回溯
代码语言:txt
AI代码解释
复制
bt 或where , info s
bt full 会打印栈里的变量

五、打印和单步调试

代码语言:txt
AI代码解释
复制
p *&argv[0]@3:表示打印argv[0] argv[1] argv[2]
p {int}argv 以int类型显示argv变量
p/x 显示十六进制
p/d 显示有符号的十进制
p/u 显示无符号的十进制
p/o 显示八进制
p/t 显示二进制
p/a 显示地址
p/c 显示符号
p/f 显示浮点数
p/r 以上一次的格式显示
x/i 显示汇编
x/s 显示字符
x/b 单字节显示
x/h 双字节显示
x/w 四字节显示
x/g 八字节显示
disassemble/disas 显示反汇编
disassemble/r 显示反汇编前的机器码 混合
disassemble/m 显示源码 混合
disas start, end
disas start, +length
$表示上一个显示的变量
$n表示上n个显示的变量
$$表示上上个显示的变量
$$n表示上n个显示的变量的值
$_表示上一个用x显示的变量
$__表示上一个用x显示地址上存放的数据
$_thread 表示最新创建的线程


p $_strlen(str) 计算str字符串的长度
p $_streq(str1, str2) 比较两个字符串是否相等,相等返回1
help function 查看可使用的函数
explore val :可以显示变量的类型
(1)观察类型
代码语言:txt
AI代码解释
复制
pt(ptype) 观察数据类型(结构)
whatis
print v@10
(2)单步跟踪
代码语言:txt
AI代码解释
复制
next /n 代码单步步过
step/s 代码单步步入
stepi(si) 单步步入
stepi 4 执行4个指令
nexti 单步步过
skip function 始终步过指定函数
skip file [filename] 始终不进入指定文件


until 3 继续执行直到命中断点3
finish 继续执行直到当前函数返回
set print finish on 继续执行到函数后会打印返回值,本机测试不成功???
call func 执行func函数并打印返回值
return result 强制返回,返回值为result

六、实用操作

代码语言:txt
AI代码解释
复制
gdb 重放操作 repeat
(1)启动参数
代码语言:txt
AI代码解释
复制
gdb ‐n :可以不加载任何gdbinit文件,不想使用插件时不必去注释gdbinit文件了
gdb ‐q :不打印版本和介绍信息启动
gdb ‐write:对二进制程序可读可写启动,可对二进制程序指令进行修改,并保存到文件中,或者启动后"set write on"
gdb ‐statistics:可打印每条指令执行的时间
调试时可以通过"|"管道符对输出结果进行处理
gdb ‐‐pid=<n> 调试已经运行的程序
(2)执行系统命令
代码语言:txt
AI代码解释
复制
 !command
(3)转储分析
代码语言:txt
AI代码解释
复制
gdb ‐‐core=<file>
gdb program core
gcore [file] 生成一个core文件用于保存当前gdb调试的快照(默认生成core.pid文件)
(4)dump 内存
代码语言:txt
AI代码解释
复制
dump 内存到文件中
dump [format] memory filename start_addr end_addr
format:binary/ihex
dump [format] value filename expr

追加内存到文件中
append [binary] memory filename start_addr end_addr
append [binary] value filename expr

从文件中恢复到内存
restore filename [binary] bias start end
(5)窗口调试
代码语言:txt
AI代码解释
复制
layout 用于分割窗口,可以一边查看代码,一边测试
layout split 显示源代码和汇编窗口
layout next 显示下一个layout
layout prev 显示上一个layout
layout regs 显示源代码/汇编和寄存器窗口
focus cmd (三个窗口:cmd、asm、src)
Ctrl + L:刷新窗口
Ctrl + x,再按1:单窗口模式,显示一个窗口
Ctrl + x,再按2:双窗口模式,显示两个窗口
Ctrl + x,再按a:回到传统模式,即退出layout,回到执行layout之前的调试窗口。
(6)搜索内存:
代码语言:txt
AI代码解释
复制
find [/sn] start_addr, +len, val1 [, val2, …]
find [/sn] start_addr, end_addr, val1 [, val2, …]
s可以为b,h,w,g等值,分别表示 字节(byte),两个字节(half words),4个字节(words),8个字节(giant words)
n表示要找的东西的最多个个数,默认是把所有的都找出来
$_ 保存着找到的最后一个地址
(7)宏处理
代码语言:txt
AI代码解释
复制
宏展开
macro exp expression
例:macro exp __is_constexpr(1)
宏展开一次
macro exp1 expression
(8)在gdb中编译和注入代码

七、设置和显示

(1)设置操作
代码语言:txt
AI代码解释
复制
set args 设置程序参数
show args 显示程序参数
set print vtbl on/off 开启打印虚表功能
set print union on/off 开启打印联合类型
set print symbol on/off 开启打印符号表
set print array on/off 开启打印数组类型
set print object on/off 开启打印object类型
set charset ASCII 设置字符集为ASCII
(2)显示符号
代码语言:txt
AI代码解释
复制
info variables/var regexp 查找变量
info classes regexp
info functions/func regexp 查找函数
info types regexp
info address symbol 查找symbol所在的地址
info symbol addr 查找地址对应的symbol,如果找不到,会返回最近的symbol+偏移
directory/dir dirname 设置符号表搜索路径
info program 显示程序状态,是否在运行,程序名,为什么停止
info stack 查看栈信息
info r 查看寄存器

八、调试特定场景

(1)调试多线程
代码语言:txt
AI代码解释
复制
info threads
thread 2 切换到线程2
thread apply [thread‐id‐list | all [‐ascending]] command
对多个线程执行命令,例如: thread apply all bt 对所有线程进行栈回溯
对当前线程命名: thread name [name]
(2)调试fork子进程
代码语言:txt
AI代码解释
复制
set follow‐fork‐mode parent/child 默认是调试父进程,而子进程继续执行
set detach‐on‐fork mode on/off 同时调试父进程和子进程
开启后可以控制所有fork的子进程,通过info inferiors查看信息,用inferior 命令进行切换

调试exec产生的子进程
set follow‐exec‐mode new/same
new 是新建一个inferior,而父进程的inferior仍然保留,当前保留的inferior的程序状态是没有执行。
same是保持在原来的inferior,gdb默认是same模式
set schedule‐multiple on 所有进程同时运行,detach‐on‐fork开启调试一个进程时,其他进程挂起
bt 显示所有参数
set print frame‐arguments all
(3)调试信号
代码语言:txt
AI代码解释
复制
info handle 查看各种信号的设置,设置包括如下:
print 对信号量进行通知
noprint 对信号量不打印信息,如果有信号量干扰,可以用handle xxx noprint将其屏蔽
stop 中断执行
nostop 不中断执行
pass 允许程序接管信号量
nopass 不允许程序接收信号量
handle SIGCONT 查看continued的信号量设置

九、随机化设置

代码语言:txt
AI代码解释
复制
关闭ASLR:
set disable‐randomization on
开启ASLR:
set disable‐randomization off
查看ASLR状态:
show disable‐randomization

默认是关闭随机化的,也就是on状态。

十、调试内核时出现“Remote 'g' packet reply is too long”问题

代码语言:txt
AI代码解释
复制
gdb源码下载:https://mirrors.ustc.edu.cn/gnu/gdb/

gdb源码根目录/gdb/remote.c里面,将
if (buf_len > 2 * rsa‐>sizeof_g_packet)
error (_(“Remote ‘g’ packet reply is too long: %s”), rs‐>buf);
修改为
if (buf_len > 2 * rsa‐>sizeof_g_packet) {
rsa‐>sizeof_g_packet = buf_len ;
for (i = 0; i < gdbarch_num_regs (gdbarch); i++) {
    if (rsa‐>regs‐>pnum == ‐1)
    continue;
    if (rsa‐>regs‐>offset >= rsa‐>sizeof_g_packet)
     rsa‐>regs‐>in_g_packet = 0;
    else
    rsa‐>regs‐>in_g_packet = 1;
    }
  }

重新编译gdb
./configure ‐‐prefix=/home/ubuntu/gdb‐8.2/install
make
sudo apt install ‐y texinfo
make install

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
gdb命令总结
info share : info sharedlibrary 查看加载了什么库,地址好像不准,maps文件的才准(其实直接输入sharedlibrary命令就行了,不过没有地址而已,不过那个地址也不准的样子)
用户1423082
2024/12/31
810
Linux多进程和多线程的一次gdb调试实例
Linux C/C++开发中gdb进行多进程和多线程的调试一直比较麻烦,在CSDN上看到高科的一篇文章《gdb调试多进程和多线程命令》比较有启发,这里就自己重新整理并做了一个GDB多进程/线程的调试实践。
typecodes
2024/03/29
4650
Linux多进程和多线程的一次gdb调试实例
linux下gdb调试方法与技巧整理「建议收藏」
GDB是一个由GNU开源组织发布的、UNIX/LINUX操作系统下的、基于命令行的、功能强大的程序调试工具。 对于一名Linux下工作的c/c++程序员,gdb是必不可少的工具;
全栈程序员站长
2022/09/01
2.8K0
linux下gdb调试方法与技巧整理「建议收藏」
GDB调试-从入门实践到原理
在上篇文章中,我们分析了线上coredump产生的原因,其中用到了coredump分析工具gdb,这几天一直有读者在问,能不能写一篇关于gdb调试方面的文章,今天借助此文,分享一些工作中的调试经验,希望能够帮到大家。
高性能架构探索
2022/08/25
3.1K0
GDB调试-从入门实践到原理
Linux下gdb的安装及使用入门
用root权限的Terminal(或一般权限的Terminal)的vi编辑器编写一个C程序a.c:
黑泽君
2018/10/11
6.8K0
GDB调试笔记
GDB是在Linux命令行下对C/C++的程序进行调试常用的一个命令, 现将平时记录在本子上的笔记整理记录一下.
evilpan
2023/02/12
1.2K0
GDB的那些奇淫技巧
gdb也用了好几年了,虽然称不上骨灰级玩家,但也有一些自己的经验,因此分享出来给大家,顺便也作为一个存档记录。
evilpan
2023/02/12
1.3K0
GDB的那些奇淫技巧
自己动手写一个GDB|基本功能
GDB 全称 the GNU Project debugger,主要用来调试用户态应用程序。
用户7686797
2022/05/17
1.4K0
自己动手写一个GDB|基本功能
GDB 调试笔记
GDB 是一个由 GNU 开源组织发布的 *.nix 下的、基于命令行的一款比较知名的程序调试工具。
zucchiniy
2020/05/22
9470
GDB使用详解
一、打开GDB 1、gdb filename 加载该文件到gdb 2、gdb file filename 如果gdb filename失败,可以在打开gdb以后,通过file来加载调试文件 3、
李海彬
2018/03/22
7.2K0
GDB使用详解
GDB入门教程
GDB(The GNU Debugger),是GNU开源组织发布的一个强大的UNIX程序调试工具。如果你是在 UNIX平台下开发软件,你会发现GDB这个调试工具有比VC、BCB的图形化调试工具拥有更强大的功能。同时GDB也具有例如DDD调试器,全称是Data Display Debugger这样的图形化调试端。
恋喵大鲤鱼
2018/08/03
2.1K0
GDB入门教程
GDB调试入门,看这篇就够了
GDB(GNU Debugger)是UNIX及UNIX-like下的强大调试工具,可以调试ada, c, c++, asm, minimal, d, fortran, objective-c, go, java,pascal等语言。本文以C程序为例,介绍GDB启动调试的多种方式。
编程珠玑
2019/07/23
7.7K0
GDB调试入门,看这篇就够了
Linux下GDB调试指令总结
之前写C++的一些程序都是在windows下,直接使用VS2017的傻瓜式编译器,最近尝试摸索在linux进行C++程序的编译,有了一些成果!特此总结!
算法工程师之路
2019/08/05
4.6K0
C语言: GDB调试技术(一)
用gdb同时调试一个运行程序和core文件,core是程序非法执行后core dump后产生的文件。
用户3479834
2021/02/03
1.1K0
C语言: GDB调试技术(一)
C/C++生态工具链——GDB调试器
GDB全称是GNU symbolic debugger,是Linux平台下最常用的一款调试器。GDB主要用于C/C++开发场景,同时也支持Go、Ada等语言的调试。GDB主要以命令行的形式在shell终端使用,它的一部分底层逻辑借助于ptrace进行实现。GDB的功能很强大,开发者可以在执行时修改函数变量的值以及程序的执行顺序,还可以在程序执行期间查看函数的调用过程、堆栈数据等,也可以利用GDB对代码进行断点调试。
Coder-ZZ
2023/02/23
1.7K0
C/C++生态工具链——GDB调试器
GDB多线程多进程调试
主要包括gdb分配的线程id号(例如1,2,3),操作系统分配的线程id(例如20568),线程的名字以及线程相关的调用栈信息。
chain
2018/06/05
12.8K3
linux内核启动过程分析
start_kernel是内核启动阶段的入口,通过单步调试,可以发现它是linux内核执行的第一个init,我们单步进入看看它做了哪些操作:
De4dCr0w
2019/02/27
4.4K0
Linux下的GDB调试器常用指令
调试开始:执行gdb [exefilename],进入gdb调试程序,其中exfilename为要调试的执行文件名,以下命令后括号内为命令的简化使用,比如 run(r),直接输入命令 r 就代表命令 run
极客开发者
2022/01/18
1.7K0
吃土记之GDB调试原理
If you are thinking of using complex kernel programming to accomplish tasks, think again. Linux provides an elegant mechanism to achieve all of these things: the ptrace (Process Trace) system call.
早起的鸟儿有虫吃
2023/04/03
1.1K0
吃土记之GDB调试原理
Linux gdb使用基础
GDB(GNU Debugger)是Linux下一款C/C++程序调试工具,通过在命令行中执行相应的命令实现程序的调试,使用GDB时只需要在shell中输入gdb命令或gdb filename(filename为可执行程序文件名)即可进入GDB调试环境。
xxpcb
2020/08/04
2.4K0
相关推荐
gdb命令总结
更多 >
领券
社区富文本编辑器全新改版!诚邀体验~
全新交互,全新视觉,新增快捷键、悬浮工具栏、高亮块等功能并同时优化现有功能,全面提升创作效率和体验
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文