w / o -fPIC的全局变量的位置

时间:2019-02-05 17:14:19

标签: c global-variables fpic

尽管存在一些有关-fPIC效果的帖子(例如,参见this SO post),但大多数内容尚不清楚。我写了一个非常简单的示例,但是我仍然无法弄清楚在全局变量的位置上没有-fPIC会发生什么。这是我的C文件:

$ cat main.c
#include <stdio.h>
int var1 = 94;
int var2 = 76;

int main(int argc, char **argv)
{
    int var1Loc = (int) &var1;
    int var2Loc = (int) &var2;
    printf("var1 address is: %d\n",var1Loc);
    printf("var2 address is: %d\n",var2Loc);
    printf("diff         is: %d\n",var2Loc-var1Loc);

    return var1+var2;
}

然后我用 -fPIC对其进行编译并运行两次:

$ gcc -Wno-pointer-to-int-cast -O0 -g -o main main.c
$ ./main
var1 address is: -2019672048
var2 address is: -2019672044
diff         is: 4
$ ./main
var1 address is: 1441697808
var2 address is: 1441697812
diff         is: 4

当我做完全相同的事情时没有 -fPIC 我得到类似的结果。我以为没有-fPIC地址 运行之间应该完全相同吗?

1 个答案:

答案 0 :(得分:2)

首字母缩写词(或initialism):ASLR-地址空间布局随机化。

ASLR上的维基百科说:

  

ASLR随机排列进程的关键数据区域的地址空间位置,包括可执行文件的基础以及堆栈,堆和库的位置。

这描述了您所看到的。随后,您发现使用:

prf = new PrefManager(parent.getContext());

关闭ASLR意味着每次运行中的地址都是相同的,无论是否有 echo 0 | sudo tee /proc/sys/kernel/randomize_va_space ,从而确认ASLR是地址更改的原因。

请注意,您的地址打印可能应使用-fPIC格式和%p参数(尽管将void *强制转换应用于地址时可能会截断数据,但是格式正确使用(int))。类型修饰符%d用于t,即两个指针之间的差。

ptrdiff_t