You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无调试信息时如何在GDB中查找指针及变量内存位置?

问题解答

1. 能否识别变量的内存位置?

可以。核心思路是利用你手中的源码,结合二进制逆向分析来定位——相同编译选项下(除了调试符号),编译器生成的栈帧布局和汇编逻辑完全一致。

2. 具体定位方法

  • 先将源码用相同编译器、相同编译参数(仅额外添加-g开启调试符号)编译出带调试信息的版本。执行objdump -dS <带调试程序>反汇编,找到main函数的汇编代码,重点看栈帧构建逻辑(比如push ebp; mov ebp, esp这类指令),同时记录buffer和p相对于栈帧基址(ebp/rbp)的偏移值——比如32位程序中,buffer可能在ebp-128位置,p在ebp-4位置。
  • 对无符号表的目标程序,执行objdump -d <无调试程序>反汇编,通过对比带调试版本的main函数汇编指令片段,定位出无调试版本中main函数的入口和范围。
  • 调试无符号表程序时,在main函数执行到栈帧构建完成后(比如刚执行完mov ebp, esp),用栈帧基址加上之前记录的偏移,就能计算出buffer和p的内存位置。

3. 使用x/x <addr of p>能否正确查看指针指向的内存地址?

可以。x/x是GDB中以十六进制格式读取指定内存地址内容的命令,而指针p本身就是一个存储目标地址的内存单元。只要你拿到了p的正确内存地址,x/x读取的结果就是p指向的地址值。注意如果是64位程序,需要用x/gx来读取8字节的完整指针值,避免截断。

4. 如何跟踪指针p在不同执行阶段的状态?

  • 先通过上述方法确定p的栈帧偏移,在GDB中给main函数的关键执行点设置断点(比如通过汇编指令地址设置:b *<main函数汇编起始地址+偏移量>)。
  • 断点触发后,直接通过栈帧基址计算p的地址,比如32位用p $ebp-4,64位用p $rbp-8(根据实际偏移调整),再用x/x查看其指向的地址;也可以直接用p *(char**)($ebp-4)(32位)来直接获取指针指向的地址。
  • 还可以给p的内存位置设置观察点:watch *<p的内存地址>,这样当p指向的地址发生变化时,GDB会自动触发断点,方便跟踪不同执行阶段的状态。

内容的提问来源于stack exchange,提问作者A. Trevelyan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 14:50:32