glibc 似乎有不止一种方法来进行堆检查:
- mallopt 与 M_CHECK_ACTION 参数
- MALLOC_CHECK_ 环境变量
- mcheck 函数系列
我发现可用的文档令人困惑。这manual http://www.gnu.org/software/libc/manual/html_node/Malloc-Tunable-Parameters.html描述 mallopt 时根本没有列出 M_CHECK_ACTION。这个 mallopt 手册页 http://man7.org/linux/man-pages/man3/mallopt.3.html, 然而,does描述M_CHECK_ACTION。此外,它表示它相当于环境变量 MALLOC_CHECK_:
MALLOC_CHECK_
This environment variable controls the same parameter as
mallopt() M_CHECK_ACTION. If this variable is set to a
nonzero value, then a special implementation of the memory-
allocation functions is used. (This is accomplished using the
malloc_hook(3) feature.) This implementation performs
additional error checking, but is slower than the standard set
of memory-allocation functions.
glibc 手册有一页mcheck和朋友们 http://www.gnu.org/software/libc/manual/html_node/Heap-Consistency-Checking.html并将它们描述为“堆一致性检查”。手册在此页讨论了 MALLOC_CHECK_:
检查和防止使用 malloc、realloc 和 free 时出现错误的另一种方法是设置环境变量 MALLOC_CHECK_。当设置 MALLOC_CHECK_ 时,将使用一种特殊的(效率较低)实现,该实现旨在容忍简单错误,例如使用相同参数对 free 进行两次调用,或单个字节的溢出(差一错误)。
那么 mcheck 等人是 MALLOC_CHECK_/M_CHECK_ACTION 的替代品吗?
此外,如何禁用所有这些超级有用的一致性检查?手册页说将 MALLOC_CHECK_ (因此 M_CHECK_ACTION)设置为 0 将不会使用“内存分配函数的特殊实现”。然而,glibc 手册指出“当设置 MALLOC_CHECK_ 时,将使用特殊的(效率较低)实现”。设置为 0 的环境变量仍然被设置,因此其中之一是错误的。
我自己的实验(使用示例程序这个 mcheck 手册页 http://man7.org/linux/man-pages/man3/mcheck.3.html)表明根本不设置 MALLOC_CHECK_ 会导致与 MALLOC_CHECK_=3 (在 RHEL 6.4 上)相同的行为。和 mcheck 似乎完全无关,因为它可以独立设置。
有四种不同的一致性检查。以下对应于 glibc 2.25。
- 各种断言。它们是否处于活动状态是在 glibc 构建时确定的。过去,Debian 和下游版本保持断言处于打开状态。 Fedora 和下游版本过去禁用了它们(但当前的 Fedora 保留了它们)。
- 核心一致性检查
malloc
不使用断言的实现,但是malloc_printerr
。过去,可以使用以下命令关闭它们MALLOC_CHECK_=0
(and mallopt
)。但是,我怀疑之后的错误恢复malloc_printerr
在所有情况下都是正确的,因此这不太可能起作用。如果存在堆损坏,程序可能很快就会崩溃。
- 相对轻量级的堆缓冲区溢出检测。这是通过以下方式启用的
MALLOC_CHECK_=3
(或另一个非零值)。无法通过以下方式打开此功能mallopt
。它是通过增加分配的大小并存储一些填充并在某些地方检查它来实现的。这个堆检查器应该是线程安全的,并且它与malloc
内部结构。然而,它很少被使用,因此很容易出现恼人的错误。
- The
mcheck
函数,调用自__malloc_initialize_hook
通过链接libmcheck.a
。这与之前的检查完全不同。我认为这个想法是通过一组单独的元数据(独立于实际分配器)来验证正确的分配行为,并且mcheck
不依赖于glibc
malloc 内部结构除了malloc
钩子。然而,它对这些钩子的使用完全不是线程安全的。我认为没有人使用mcheck
今天。它只是被包含在内,因为还没有人删除它。 (甚至不需要向后兼容,因为不能保证检测到所有堆损坏,并且损坏堆的应用程序仍然完全未定义,因此无法检测是否mcheck
实际上执行额外的检查。)
除此之外,还有MALLOC_PERTURB_
,可用于检测对未初始化或已释放数据的某些形式的访问。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)