主要观点:通过自定义内存分配器的测试,发现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) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。