gdb调试需要使用到的一些知识(心得)

 

为了更好的使用gdb来调试程序,需要具备一下技能:

gdb的基本调试手段,比如b **.c:fun linenum 设置断点 , next:单步执行, step 单步调试,可以跟踪进函数。注意编译的时候要加上-g选项。

info reg:查看寄存器状态。info locals:查看局部变量 p:打印变量的值 l:显示代码。x:以16进制的方式打印地址中的值。

linux内存分配原理:局部变量放在栈中,栈外向低地址增长,栈内向高地址端增长;malloc的空间在堆上,堆外向高地址端增长,堆内向低地址端增长;代码放在代码段;全局变量和静态放在数据段;未初始化的数据放在bss数据段。linux的32为位线性地址空间4G,从0xbfffffff开始往下是栈,从0x08000000开始往上依次是代码段,已初始化的全局变量和静态变量的数据段,未初始化的全局变量和静态变量的数据段,malloc动态分配的空间。在中间0x40000000往上是linux给共享内存分配的线性地址空间。

程序运行基本入栈原理:首先介绍3个重要的寄存器:%ebp,%esp,%eip。%ebp:存放栈底地址,%esp:存放栈顶地址,%eip:存放下一条要运行的汇编代码的地址。例如:一个func1函数调用一个func2函数,那么call func2之前一般会将func2函数需要使用的参数从右到左依次入栈,然后call func2这条语句会引发以下动作,将call func2的下一条要执行的汇编代码的地址入栈,将%ebp入栈(即func1函数的栈底地址入栈),之后便进入func2函数了,会将他要用到的局部变量和他需要保存的一些寄存器入栈,如果你用gdb跟踪到此处,运行info reg你便可以清楚的看到%eip中存放了一个地址,你如何确认他就是call func2之后要执行的那条语句的地址呢?你运行disassemble func1便可以看到call func2之后运行的汇编代码的地址了,好奇的你如果还想进一步看看栈中是否有之前说的将call func2的下一条要执行的汇编代码的地址入栈,你可以运行x/n %ebp(**表示你希望打印地址之后4n个字节地址中的值。)。一般每个函数推出的时候都会执行ret,目的是为了将此函数的数据退栈,他会做一些准备,首先mov %ebp %esp之后将%ebp中的值(即上一层函数func1的栈底地址)出栈,此时%esp便指向了call func2之后要执行的汇编代码的地址了。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值