在一种检测堆损坏的方法中,我试图实现一个哈希表来保存一些关于被错误分配的内存的信息。这是在glibc内部完成的。当我们使用malloc()时,我们将地址和大小等信息放入哈希表中,当我们使用free()时,我们释放相应的哈希表条目,同样在glibc的free()本身中。
为哈希表分配内存,我已经mmap了一些内存(避免使用malloc,因为进程引起的堆损坏的可能性也会损坏我的哈希表)。问题是进程可以请求的malloc数量没有限制,这要求我的哈希表是可扩展的。由于我的哈希表在数组索引上工作,因此用于哈希表的内存需要是连续的,以便使用索引我们可以轻松地到达桶或记录。现在,当哈希表使用所有内存时,我需要再次执行'mmap',以使该内存从先前结束的地方开始。mmap的手册页说,我们可以为mmap提供一个地址,这将作为内核映射到该地址的虚拟内存的提示。对于哈希表,它看起来就像一个连续的内存块。我想问一下您的建议,这种方法有多可靠,使用这种方法有哪些潜在的缺陷。
如果是Linux,可以使用mremap
如果你写你的哈希表是基于偏移量,而不是绝对指针,你可以传递MREMAP_MAYMOVE
标志,永远不必担心分配失败。(好吧,直到你用尽你的虚拟内存。)
这种方法有多可靠
MAP_FIXED
是非常可靠的:如果你所要求的内存是可用的,内核会给你。
潜在的陷阱是什么
最明显的一个:其他东西可能已经让mmap
进入了您想要扩展到的区域,而您输了。
如果你在64位进程中这样做,你可以mmap
例如1TB的内存作为你的初始哈希表分配。只要您不实际访问它,这个mmap
实际上是免费的(成本),假设您正在做MA_ANON
映射。
顺便说一句,我希望您意识到您在这里重新发明了一辆自行车,因为许多现有的解决方案(如tcmalloc和jemalloc)已经提供了可能比您自己编造的更好的调试工具。