gdb 条件断点_GDB高级技巧:同一个Bug,5种解决方案,不修改源码,不重新编译

1、引言

在《GDB高级技巧:边Debug边修复BUG,无需修改代码,无需重新编译》一文中,介绍了使用GDB breakpoint command lists的功能,可以在不修改源码、不重新编译的前提下,修复掉被调试程序中的BUG,从而避免反复修改代码和编译构建的过程,大大提高程序调试的效率。

文中提到了解决一个问题的几种不同的思路,但限于篇幅,只重点讲解了其中的一种。有童鞋希望能够把其它几种也讲解一下,于是便有了此文。

本文会介绍5种不同的方法,解决同一个Bug!

2、本文要解决的问题

如下示例程序中,存在两个BUG:

7e065f0805ec76c88ea8c6c4c072d372.png

图1 示例程序

正常执行时,该程序将出现异常,如下图所示:

9be2a1d38205ffc9f38822182085c146.png

图2 原始程序执行异常

本文将介绍5种方法,在不修改源码、不重新编译的前提下,借助GDB解决掉示例程序中的两个BUG,使其能够正确执行,并得到预期结果。

其最终执行结果如下图所示:

63e65c3ac25783f5b1022db482f9ee87.png

图3 程序最终可以正常执行

先介绍一些必需的背景知识。

3、背景知识介绍

3.1、x64 CPU函数参数传递

对于C语言,不同的CPU/编译器,其参数传递方式也不尽相同。

我的测试环境是x64CPU,所以仅介绍x64 CPU的函数参数传递规则。

用GCC编译出来的程序,在x64 CPU上,如果程序中没有特殊指定,会优先使用寄存器传递参数,当寄存器不够用的时候,用栈传递。

默认情况下,前6个参数,从左到右,依次用寄存器RDI(EDI)、RSI(ESI)、RDX(EDX)、RCX(ECX)、R8、R9传递,从第七个函数开始,使用栈传递

注:RDI、RSI、RDX、RCX是64位寄存器,EDI、ESI、EDX、ECX分别是它们低32位寄存器的表示。

如下图简单示例:

c8b7e9c99780dbd85b0941d01b55f6fc.png

图4 参数传递示例

test()共有8个参数,我们在GDB中把main()函数反汇编一下,看下是如何传递参数的:

20b2bdb2e8c74bda9b517f448ff93f3a.png

图5 main反汇编

通过反汇编,可以看到,前面6个参数是使用寄存器传递的,而第7、8两个参数是通过栈传递的。

3.2、GDB断点预置命令

注:已阅读过之前那篇文章的童鞋,可以直接跳过3.1小节。当然, 也可以再回顾一下,加深印象࿰

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值