C函数在从同一函数调用时更改运行时的返回地址

时间:2016-09-15 13:26:11

标签: c

我想知道在从同一个函数调用时,C函数在哪些情况下可以运行时更改其返回地址

我注意到它发生在我开发的低级代码的一系列测试中。 这是一个片段,显示我如何检索两个指针:

#include <stdint.h>

uintptr_t foo() {
    // Fetch the current IP and SP
    uintptr_t ip = (uintptr_t)__builtin_return_address(0);
    register void* rsp asm("sp");
    uintptr_t sp = (uintptr_t)rsp;
    return ip + sp; // just to avoid that they are optimized away.
}

void bar () {
    foo();
}

当我运行我的测试并从不同的函数调用bar时,我看到IP的值发生了变化(不是非常频繁,在一系列长时间的测试中只有一次)。

虽然我的编译器可能会内联函数。但是,即使将__attribute__((noinline))应用于这两个函数,我也会看到错误发生。

我知道不可靠,因为它可能会被优化掉。

您对此问题有任何其他解释或解决方案吗?

我正在使用GNU / Linux内核3.10.39下的gcc 4.7.2进行编译。

1 个答案:

答案 0 :(得分:4)

“返回地址”是函数返回的地址。如果你从几个地方打电话,很快就会明白为什么会发生这种情况。

堆栈指针取决于我们当前所在堆栈的深度,因此取决于通话记录:如果 var myApp = angular.module('myApp',[]); myApp.controller('repeatCtrl', function($scope) { $scope.list = [ {id: 'a', checked :true,test:{sub:{var:4}}}, {id: 'b', checked:true,test:{sub:{var:3}}}, {id: 'c', checked:true,test:{sub:{var:2}}}, {id: 'd', checked:true,test:{sub:{var:2}}}, {id: 'e', checked:true,test:{sub:{var:3}}} ]; $scope.myPrecious = 2; }); 调用调用main() a()调用b() },您与foo()直接调用SP的{​​{1}}不同。