C&C++   发布时间:2022-04-01  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了malloc中的系统调用brk和mmap大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
@H_126_0@malloc中的系统调用brk和mmap
环境
  • ubuntu14.04

  • @H_459_6@malloc通过系统调用的方式从操作系统申请内存,malloc内部又通过系统调用brk()或@H_69_11@mmap来申请内存的。入下图进程虚拟内存布局所示,mmap对应@H_69_11@memory Mapping Segment,brk对应Heap.

malloc中的系统调用brk和mmap

@H_944_27@brk
  • brk通过增加program break的位置(brk)从内核申请(非零值初始化)内存。一开始堆段(heap segment)的其实位置(starT_Brk)和结束位置(brk)指向同一个位置。

    • 当ASLR(Address Space Layout Randomization)关闭时,starT_Brkbrk同时指向data/bss段的结束位置(end_data)
    • 当ASLR打开时,starT_Brk和brk同时指向data/bss段的结束位置(end_data)再加上一个随机的brk偏移。
  • 上面的进程虚拟内存布局展示了,starT_Brk是堆段的开始位置 ,brk(program break)是堆栈的结束位置。

例子

/* sbrk, brk 例子 */
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>

int main()
{
        void *curr_brk, *tmp_brk = NULL;

        printf("Welcome to sbrk example:%d\n", getpid());

        /* sbrk(0) 获取当前 program break 位置 */
        tmp_brk = curr_brk = sbrk(0);
        printf("Program Break LOCATIOn1:%p\n", curr_brk);
        getchar();

        /* 使用 brk 增加 program break 位置 */
        brk(curr_brk+4096);

        curr_brk = sbrk(0);
        printf("Program break LOCATIOn2:%p\n", curr_brk);
        getchar();

        /* 使用 brk 减小 program break 位置 */
        brk(tmp_brk);

        curr_brk = sbrk(0);
        printf("Program Break LOCATIOn3:%p\n", curr_brk);
        getchar();

        return 0;
}
  • 在增加program break之前,输出如下:

    malloc中的系统调用brk和mmap

  • starT_Brk=brk=end_data=0x602000

  • 在增加program break之后,输入如下:

    malloc中的系统调用brk和mmap

  • starT_Brk=end_data=0x602000,brk=0x603000.

  • 可以观察到堆段

00602000-00603000 rw-p 00000000 00:00 0                                  [heap]
  • 00602000-00603000是堆段的虚拟地址范围
  • rw-p的标准含义是Read、Write、 NoeXecute、Private
  • 00000000 是文件偏移量,由于没有映射任何文件所以为0
  • 00:00 是major/minor device number,由于没有映射任何文件所以为0
  • 0是inode 也是没有映射任何文件所以为0
  • 【heap】是堆段
@H_111_109@mmap
    @H_353_5@malloc使用mmap创建一个私有匿名的映射段,这个映射段的主要目的是申请一块(零值初始化的)新内存,并且这块内存只能被调用的这个进程独占使用。
/* 使用mmap系统调用做私有匿名映射的例子 */
#include <stdio.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>

void static inline errExit(const char* msg)
{
        printf("%s failed. ExiTing the process\n", msg);
        exit(-1);
}

int main()
{
        int ret = -1;
        printf("Welcome to private anonymous mapping example::PID:%d\n", getpid());
        printf("Before mmap\n");
        getchar();
        char* addr = NULL;
        addr = mmap(NULL, (size_t)132*1024, PROT_READ|PROT_WRITE, MAP_PRIVATE | MAP_ANONymOUS, -1, 0);
        if (addr == MAP_FAILED)
                errExit("mmap");
        printf("After mmap\n");
        getchar();

        /* Unmap mapped region. */
        ret = munmap(addr, (size_t)132*1024);
        if(ret == -1)
                errExit("munmap");
        printf("After munmap\n");
        getchar();
        return 0;
}
  • 调用mmap之前:可以看到,属于libc.so和ld-linux.so共享库的内存映射段。

    malloc中的系统调用brk和mmap

  • 调用mmap之后:如下我们可以看到,mmap映射的内存段已经从上图红色框内分配出去(0xe0000-0xbf000=0x21000).

malloc中的系统调用brk和mmap

  • 调用munmap之后,如下输出可以看到mmap已经被解除映射了。

malloc中的系统调用brk和mmap

大佬总结

以上是大佬教程为你收集整理的malloc中的系统调用brk和mmap全部内容,希望文章能够帮你解决malloc中的系统调用brk和mmap所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。
标签: