原文:Hack The Virtual Memory: C strings & /proc - Holberton翻译:RobotCode俱乐部
原文:Hack The Virtual Memory: C strings & /proc - Holberton
我们之前讨论过在进程的虚拟内存中可以找到什么,以及在哪里可以找到它。今天,我们将尝试「重建」下图,方法是列印程序中各个元素的地址。
我们要在图中定位的第一个区域就是栈。我们知道在C语言中,局部变数位于栈上。如果我们列印一个局部变数的地址,它应该会告诉我们在虚拟内存中哪里可以找到栈。让我们使用下面的程序来找出各种元素在内存中的分布:
#include <stdlib.h> #include <stdio.h> #include <string.h> /** * main - print locations of various elements * * Return: EXIT_FAILURE if something failed. Otherwise EXIT_SUCCESS */ int main(void) { int a;
printf("Address of a: %p ", (void *)&a); return (EXIT_SUCCESS); }
(译者注:实际程序被我修改了下,在printf后加了while(1);以方便我们观察maps)
如上图所示,局部变数显然们于[stack]区。(译者注:但是静态局部变数不是放在stack区,而是放在heap区,后面再讨论)
当你为变数malloc空间时,将使用堆。让我们添加一行代码来使用malloc,看看malloc返回的内存地址位于哪里(main-1.c):
#include <stdlib.h> #include <stdio.h> #include <string.h> /** * main - print locations of various elements * * Return: EXIT_FAILURE if something failed. Otherwise EXIT_SUCCESS */ int main(void) { int a; void *p;
printf("Address of a: %p ", (void *)&a); p = malloc(98); if (p == NULL) { fprintf(stderr, "Cant malloc "); return (EXIT_FAILURE); } printf("Allocated space in the heap: %p ", p); return (EXIT_SUCCESS); }
如上图很显然可以看出堆与栈的分布情况。可以画出如下图所示的图:
你的程序也在虚拟内存中。如果我们列印主函数的地址,我们应该知道与栈和堆相比,程序的位置。让我们看看它是否像预期的那样位于堆下面(main-2.c):
printf("Address of a: %p ", (void *)&a); p = malloc(98); if (p == NULL) { fprintf(stderr, "Cant malloc "); return (EXIT_FAILURE); } printf("Allocated space in the heap: %p ", p); printf("Address of function main: %p ", (void *)main); return (EXIT_SUCCESS); }
看起来我们的程序代码的确位于堆之下,这是意料之中的。
但我们要确保这是程序的实际代码,而不是指向其他位置的指针。让我们用objdump来分析我们的程序2,看看主函数的「内存地址」:
我们找到了完全相同的地址(0x8048464)。如果你仍然有任何疑问,可以列印位于这个地址的第一个位元组,以确保它们匹配objdump 的输出,看如下程序:
#include <stdlib.h> #include <stdio.h> #include <string.h> /** * main - print locations of various elements * * Return: EXIT_FAILURE if something failed. Otherwise EXIT_SUCCESS */ int main(void) { int a; void *p; unsigned int i;
printf("Address of a: %p ", (void *)&a); p = malloc(98); if (p == NULL) { fprintf(stderr, "Cant malloc "); return (EXIT_FAILURE); } printf("Allocated space in the heap: %p ", p); printf("Address of function main: %p ", (void *)main); printf("First bytes of the main function: "); for (i = 0; i < 15; i++) { printf("%02x ", ((unsigned char *)main)[i]); } printf(" "); return (EXIT_SUCCESS); }
如上图所示,完全符合预期。更新下我们通过实验确认后的内存分布图:
本篇到此为止,下篇再讨论命令行参数与环境变数在内存中的分布情况
--未完待续
由于本人水平有限,翻译必然有很多不妥的地方,欢迎指正。同时,欢迎关注下方微信公众号,一起交流学习:)
由于本人水平有限,翻译必然有很多不妥的地方,欢迎指正。