x86_64系统GDB中RBP与RSP重合,如何访问栈尾?
x86_64系统中GDB调试时无法用RSP访问栈尾的替代方法
我在x86_64系统使用GDB调试时发现,创建新栈帧后RBP与RSP指向同一内存地址,因此无法用RSP寄存器引用栈尾(其他系统中RSP通常用于跟踪栈尾地址)。我使用以下测试代码验证:
#include <stdio.h> void test_function(int a, int b, int c, int d) { int flag; char buffer[10]; flag = 31337; buffer[0] = 'A'; } int main(){ test_function(1, 2, 3, 4); }
调试时发现函数序言中没有针对RSP的sub指令。请问在无法使用RSP的情况下,还有其他访问栈尾的方法吗?我是新手,可能存在认知盲区。
解决方法:
- 通过RBP偏移计算栈尾:栈是向下生长的,局部变量都以RBP为基准做偏移。你可以先在GDB里执行
p &buffer或p &flag查看局部变量地址,再结合变量大小推算栈尾。比如buffer占10字节、flag占4字节,栈尾大概在$rbp - 14的位置(栈地址从高到低分配,局部变量依次往低地址存放)。用x/20x $rbp-20这类命令可以查看该区域的栈内存,确认栈尾位置。 - 查看编译器生成的汇编代码:用
gcc -S test.c生成汇编文件,直接看函数里的局部变量布局。比如你会看到flag对应-4(%rbp),buffer对应-14(%rbp),那-14(%rbp)就是栈上最靠近栈尾的局部变量地址,也就是你要找的栈尾位置。 - 关闭编译器优化:你遇到的情况基本是编译器开启了优化(比如
-O2),导致函数没有分配额外栈空间,甚至用寄存器替代了局部变量。改用gcc -g -O0 test.c编译,这样函数序言会出现sub $0x10, %rsp这类指令,RSP和RBP会分开,就能正常用RSP跟踪栈尾了。
内容的提问来源于stack exchange,提问作者strjak
相关产品推荐
相关产品推荐

