主要观点:通过自定义内存分配器的测试,发现sbrk函数在特定条件下会出现意外成功的情况,深入研究后发现是内核在brk需要分配新页面时检查RLIMIT_AS设置的限制,且RLIMIT_AS和RLIMIT_DATA在处理方式上存在差异,作者提交了内核补丁说明此问题并收到了回复。
关键信息:
- 测试用例通过
getrlimit和setrlimit限制地址空间增长,使用my_malloc分配内存并断言malloc返回NULL来测试内存耗尽情况,但测试用例中调用malloc错误,实际测试的是libc malloc的行为。 - 正常情况下,
sbrk调用因setrlimit限制而返回失败,libc malloc返回NULL;但当malloc转发到my_malloc时,sbrk会意外成功并分配新内存块,后续再次调用sbrk会在一定次数后失败。 setrlimit文档说明RLIMIT_AS限制进程总可用内存,sbrk等函数在超出限制时会失败,但实际情况中RLIMIT_AS限制在brk不跨越页面边界时可能被突破。RLIMIT_DATA与RLIMIT_AS类似,但其在brk页面对齐前检查setrlimit违规情况,将RLIMIT_DATA代入测试用例可得到预期行为。- 作者提交内核补丁说明
brk在检查请求内存量是否有效时应先检查RLIMIT_AS,但收到回复认为此补丁不正确,因为内核内存分配以页面为粒度,限制不会阻止现有资源的使用。
重要细节: - 测试用例代码及各函数的功能和调用关系,如
my_malloc、malloc、getrlimit、setrlimit、sbrk、brk等。 - 内核中
brk函数的源代码及相关逻辑,如页面大小的处理、newbrk和oldbrk的比较等。 - 提交的内核补丁内容及回复内容的详细讨论。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用。你还可以使用@来通知其他用户。