【发布时间】:2010-12-14 03:52:44
【问题描述】:
我知道,如果我在某个函数 foo() 中,该函数是从 bar() 函数的某处调用的,那么这个返回地址会被压入堆栈。
#include <stdio.h>
void foo()
{
unsigned int x;
printf("inside foo %x\n", &x);
}
int main()
{
foo();
printf("in main\n");
return 0;
}
在上面的代码中,当 foo 函数处于活动状态时,我将获得第一个压入堆栈的局部变量的地址。如何访问在堆栈上此变量之前某处推送的返回地址(主要称为 foo)?该位置是否固定并且可以相对于第一个局部变量进行访问?我该如何修改它?
编辑:我的环境是带有 gcc 编译器的 x86 处理器上的 Ubuntu 9.04。
【问题讨论】:
-
"如何修改?" - 考虑使用 setjmp/longjmp。
-
我猜 void * __builtin_return_address (unsigned int level) 不会解决我的问题。它会返回给我一个返回地址,而不是返回地址的位置。如果我应该重新表述上述问题陈述,请告诉我。
-
没有简单、可靠的方法来做你想做的事,即使你已经限制在 x86 上使用 gcc。我只能建议您提出另一个问题来说明您的实际问题。如果不出意外,修改链接指针并不能保证成功返回到您在其中写入的地址。调用站点 A 在调用 foo 之前保存了一些寄存器。调用站点 B 可能保存了不同的寄存器,并且无论恢复它们所做的一切都会失败,因为堆栈处于 A 离开它的状态,而不是 B 期望的状态。