首页 > 解决方案 > glibc 中的暂存缓冲区是什么意思?

问题描述

我发现如果我使用 tcmalloc 堆检查器以 draconian 模式检查下面的代码会导致堆泄漏,但 LSan 没有发现泄漏
(我假设 glibc 中的内部分配在 LSan 中被抑制)

#include <string.h>
#include <netdb.h>

int foo() {
    struct addrinfo hints, *res;
    memset(&hints, 0, sizeof hints);

    getaddrinfo("www.example.com", 0, &hints, &res);

    freeaddrinfo(res);
}

int main() {
    foo();
}

我检查了一下,发现在 glibc 内部getaddrinfo()使用了暂存缓冲区
, 并怀疑这些暂存缓冲区会导致内存泄漏
(即使它无害)

但遗憾的是没有完整的解释
,只说“暂存缓冲区是具有堆栈默认分配的可变大小缓冲区”;;

但究竟是什么暂存缓冲区?

你可以参考glibc/include/scratch_buffer.h 这里

标签: cglibclibctcmallocleak-sanitizer

解决方案


来自 google-perftools 的自述文件:

为了捕获所有堆泄漏,tcmalloc 必须最后链接到您的可执行文件中。堆检查器可能会错误地描述链接行上列出的库中的某些内存访问。例如,它可能会将这些库报告为内存泄漏,而实际上它们不是。(有关详细信息,请参阅源代码。)

通常,libc 最后链接。

暂存缓冲区或暂存空间是一个经常用于预分配内存的术语(因为启动时间通常比运行时性能更重要),用于各种东西。我不知道它在 glibc 中的确切用法,但我只是假设他们需要一个缓冲区来进行内部计算。他们不是动态分配,而是使用预先分配的暂存缓冲区。

LSan 支持抑制一些泄漏,但您必须检查自己是否以及哪些抑制在您的构建中处于活动状态。

至于严厉模式:我强烈怀疑暂存缓冲区是在您的main函数之前分配并在它之后释放的。在这种情况下,HeapChecker 会报告它。不要太担心它。


推荐阅读