加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Linux > 正文

在Linux中对sbrk(0)的初始调用是否总是返回一个与8个字节对齐的

发布时间:2020-12-14 00:34:51 所属栏目:Linux 来源:网络整理
导读:我正在研究这里定义的malloc的实现: http://www.inf.udec.cl/~leo/Malloc_tutorial.pdf. 作者创建了一个自然地在4字节边界上对齐的元数据结构,然后在元数据结构之后将x字节的请求与4字节边界对齐,该元数据结构实际上充当块的头部. pdf指出,由于元数据和请求
我正在研究这里定义的malloc的实现:

http://www.inf.udec.cl/~leo/Malloc_tutorial.pdf.

作者创建了一个自然地在4字节边界上对齐的元数据结构,然后在元数据结构之后将x字节的请求与4字节边界对齐,该元数据结构实际上充当块的头部. pdf指出,由于元数据和请求现在已对齐,因此结果数据将完全对齐.
如果对sbrk()的第一次调用返回与4字节边界对齐的堆的基址,则结果可以解决. sbrk()总是在初始调用中返回4字节(或64位系统的情况下为8字节)对齐的地址吗?

解决方法

standard for brk and sbrk明确没有指定返回的地址是否以任何方式对齐.在Mac OS X(可能还有其他BSD系统)上,大小/地址是页面对齐的,但在Linux上没有这样的舍入,因为可以使用这个小程序轻松测试:

#include <unistd.h>
#include <stdio.h>

int main() {
        void *p;
        p = sbrk(0);
        printf("Initial brk: %pn",p);
        p = sbrk(1); // Increase the brk (returns OLD brk!)
        p = sbrk(0); // Get the new brk
        printf("New brk: %pn",p);

        return 0;
}

在我的一个系统上,输出是:

Initial brk: 0x602000
New brk: 0x602001

但你问了最初的电话. Linux手册页指出:

brk() and sbrk() change the location of the program break,which defines the end of the process’s data segment (i.e.,the program break is the first location after the end of the uninitialized data segment). Increasing the program break has the effect of allocating memory to the process; decreasing the break deallocates memory.

单位化数据段也称为BSS.这里的关键字是段,因此初始值很可能始终是页面对齐的.

如果您想要安全并检查,您可以通过获取页??面大小的模数来验证初始地址(您可以通过getpagesize查询).

更新:所以我好奇并且挖了一点.在man-page中,我已经读过brk和sbrk是在内核的sys_brk上实现的.它在内核源代码中的实现可以在mm / mmap.c中找到(对于没有内存管理单元的系统,可以找到mm / nommu.c;我们将忽略这一点).在mm / mmap.c中的brk实现中,我们找到了这一行:

newbrk = PAGE_ALIGN(brk);

(“brk”这里是参数,而不是函数.)所以内核确实进行页面对齐…排序:虽然计算是使用页面对齐的值完成的,并且任何必要的内存分配是页面对齐的,但是存储的值是brk实际上是你传递的指针值:

mm->brk = brk;

因此,在用户空间中,即使内核确实发生了任何页面操作,它看起来也不像.我看了3.17.5和2.4.37版本,行为是一样的.

关于初始值,在fs / binfmt_elf.c(实现ELF链接)中,我们找到一个函数set_brk,它设置初始“brk”值(mm-> start_brk).该值明确是页面对齐的.对于处理旧的a.out格式的fs / binfmt_aout.c和处理HP-UX SOM格式的fs / binfmt_som.c(之前从未听说过),情况也是如此.还有fs / binfmt_flat.c,它设置初始brk值但没有明确对齐;这里的值是隐式对齐的.所以看起来初始值始终是页面对齐的.至少它保证与ELF文件页面对齐,这是我们关心的“普通”系统.

glibc简单地包装sys_brk并添加簿记以正确实现sbrk.因此glibc的brk行为是内核的行为,返回值sys_brk存储在内部隐藏变量__curbrk中,以便sbrk可以正确计算新地址.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读