关于Linux进程内存布局的问题

发布于 2024-11-18 19:26:58 字数 2898 浏览 4 评论 0原文

我说的是Intel 32位平台。 Linux 内核版本 2.6.31-14。

#include <stdio.h>
#include <stdlib.h>

int init_global_var = 10;        /* Initialized global variable */
int global_var;                  /* Uninitialized global variable */
static int init_static_var = 20; /* Initialized static variable in global scope */
static int static_var;           /* Uninitialized static variable in global scope */

int main(int argc, char **argv, char **envp)
{
        static int init_static_local_var = 30;   /* Initialized static local variable */
    static int static_local_var;             /* Uninitialized static local variable */
    int init_local_var = 40;                 /* Initialized local variable */
    int local_var;                           /* Uninitialized local variable */
    char *dynamic_var = (char*)malloc(100);  /* Dynamic variable */

    printf("Address of initialized global variable: %p\n", &init_global_var);
    printf("Address of uninitialized global variable: %p\n", &global_var);
    printf("Address of initialized static variable in global scope: %p\n", &init_static_var);
    printf("Address of uninitialized static variable in global scope: %p\n", &static_var);
    printf("Address of initialized static variable in local scope: %p\n", &init_static_local_var);
    printf("Address of uninitialized static variable in local scope: %p\n", &static_local_var);
    printf("Address of initialized local variable: %p\n", &init_local_var);
    printf("Address of uninitialized local variable: %p\n", &local_var);
    printf("Address of function (code): %p\n", &main);
    printf("Address of dynamic variable: %p\n", dynamic_var);
    printf("Address of environment variable: %p\n", &envp[0]);
    char* p=0x0;
    printf("%s\n",p);

    exit(0);
}

输出:

naman@naman-laptop ~> ./a.out
Address of initialized global variable: 0x804a020
Address of uninitialized global variable: 0x804a03c
Address of initialized static variable in global scope: 0x804a024
Address of uninitialized static variable in global scope: 0x804a034
Address of initialized static variable in local scope: 0x804a028
Address of uninitialized static variable in local scope: 0x804a038
Address of initialized local variable: 0xbfc11cbc
Address of uninitialized local variable: 0xbfc11cb8
Address of function (code): 0x8048484
Address of dynamic variable: 0x8223008
Address of environment variable: 0xbfc11d7c
fish: Job 1, “./a.out” terminated by signal SIGSEGV (Address boundary error)

在上面的代码中,我有以下困惑。 为什么代码位于 0x8048484 处,而不是位于虚拟内存开头附近的某个位置,例如 0x00000400 ?据我所知,布局应该是这样的:

低内存...................................... ........HighMemory

Text Data BSS Heap.....................Stack Env

因此,文本不应该位于内存中太远的地方。它应该靠近较低的内存,不是吗?

I am talking about Intel 32-bit platform. Linux kernel version 2.6.31-14.

#include <stdio.h>
#include <stdlib.h>

int init_global_var = 10;        /* Initialized global variable */
int global_var;                  /* Uninitialized global variable */
static int init_static_var = 20; /* Initialized static variable in global scope */
static int static_var;           /* Uninitialized static variable in global scope */

int main(int argc, char **argv, char **envp)
{
        static int init_static_local_var = 30;   /* Initialized static local variable */
    static int static_local_var;             /* Uninitialized static local variable */
    int init_local_var = 40;                 /* Initialized local variable */
    int local_var;                           /* Uninitialized local variable */
    char *dynamic_var = (char*)malloc(100);  /* Dynamic variable */

    printf("Address of initialized global variable: %p\n", &init_global_var);
    printf("Address of uninitialized global variable: %p\n", &global_var);
    printf("Address of initialized static variable in global scope: %p\n", &init_static_var);
    printf("Address of uninitialized static variable in global scope: %p\n", &static_var);
    printf("Address of initialized static variable in local scope: %p\n", &init_static_local_var);
    printf("Address of uninitialized static variable in local scope: %p\n", &static_local_var);
    printf("Address of initialized local variable: %p\n", &init_local_var);
    printf("Address of uninitialized local variable: %p\n", &local_var);
    printf("Address of function (code): %p\n", &main);
    printf("Address of dynamic variable: %p\n", dynamic_var);
    printf("Address of environment variable: %p\n", &envp[0]);
    char* p=0x0;
    printf("%s\n",p);

    exit(0);
}

Output:

naman@naman-laptop ~> ./a.out
Address of initialized global variable: 0x804a020
Address of uninitialized global variable: 0x804a03c
Address of initialized static variable in global scope: 0x804a024
Address of uninitialized static variable in global scope: 0x804a034
Address of initialized static variable in local scope: 0x804a028
Address of uninitialized static variable in local scope: 0x804a038
Address of initialized local variable: 0xbfc11cbc
Address of uninitialized local variable: 0xbfc11cb8
Address of function (code): 0x8048484
Address of dynamic variable: 0x8223008
Address of environment variable: 0xbfc11d7c
fish: Job 1, “./a.out” terminated by signal SIGSEGV (Address boundary error)

In the above code, I have the following confusion.
Why does the code lie at 0x8048484 instead of somewhere near the start of virtual memory like, say, 0x00000400? As far as I know, the layout should be like this:

Low memory........................................HighMemory

Text Data BSS Heap.....................Stack Env

So,text should not lie so far down the memory. It should be close to the lower memory, shouldn't it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

乖乖哒 2024-11-25 19:26:58

为什么代码位于0x8048484

因为默认加载地址(ELF文件的开头将加载在此地址)是0x8000000(或0x8048000)。此默认值在默认链接器 (ld) 脚本中固定,并且可以通过链接器选项进行更改。

请注意,这是 0x08000000 或 0x08048000(128 MB),而不是 0x80000000(2 GB)。

以下是有关此限制的一些讨论 http://cboard.cprogramming.com/tech-board/101129-why-address-space-0-0x08000000-process-unused.html 在论坛和 http://books.google.com/books?id=Id9cYsIdjIwC&pg=PA111&lpg=PA111&dq=linker+0x08000000 在图书中。
http://lkml.org/lkml/2002/2/20/194 在 lkml 有很好的描述:

“0x8048000是文本段的典型起点,根据
符合 System V Intel 386 ABI 规范
http://stage.caldera.com/developer/devspecs/abi386-4。 pdf)。”

Why does the code lie at 0x8048484

Because default load address (begin of ELF file will be loaded at this address) is 0x8000000 (or 0x8048000). This default is fixed in default linker (ld) script and can be changed via linker options.

Note, this is 0x08000000 or 0x08048000 (128 megabytes) and not a 0x80000000 (2 gigabytes).

Here is some discussion about this limit http://cboard.cprogramming.com/tech-board/101129-why-address-space-0-0x08000000-process-unused.html at forums and http://books.google.com/books?id=Id9cYsIdjIwC&pg=PA111&lpg=PA111&dq=linker+0x08000000 in books.
Also http://lkml.org/lkml/2002/2/20/194 at lkml with good description:

"0x8048000 is the typical starting point for the text segment according
to the System V Intel 386 ABI specification
(http://stage.caldera.com/developer/devspecs/abi386-4.pdf)."

她说她爱他 2024-11-25 19:26:58

什么时候 a.out 不是 a.out?当它实际上是一个ELF时。尝试 elfinfo --all a.out 了解详细信息。

When is an a.out not an a.out? When it is actually an ELF. Try elfinfo --all a.out for details.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文