gpt4 book ai didi

c - glibc 中的暂存缓冲区是什么意思?

转载 作者:行者123 更新时间:2023-12-04 10:14:53 25 4
gpt4 key购买 nike

我发现如果我使用 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();
}

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

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

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

你可以引用 glibc/include/scratch_buffer.h here

最佳答案

在内部,所有 NSS 接口(interface)(getaddrinfo 是其中之一)看起来像 gethostbyname_r :

   int gethostbyname_r(const char *name,
struct hostent *ret, char *buf, size_t buflen,
struct hostent **result, int *h_errnop);

调用者通过 buf 为结果数据提供一个缓冲区。 , buflen字节。如果事实证明这个缓冲区的大小不够,函数会失败并返回 ERANGE。错误。调用者应该增长缓冲区(以某种方式重新分配它)并调用函数,其他参数相同。这会重复,直到缓冲区足够大并且函数成功(或函数由于其他原因而失败)。我们如何最终得到这个奇怪的界面是一个较长的故事,但它是我们今天拥有的界面。 getaddrinfo看起来不同,但内部支持的实现与公共(public) gethostbyname_r 非常相似功能。

因为 retry-with-a-larger-buffer 习惯用法在整个 NSS 代码中非常常见, struct scratch_buffer被介绍了。 (以前,固定缓冲区大小的组合相当不拘一格, allocaallocamalloc 后备等等。) struct scratch_buffer组合了一个固定大小的堆栈缓冲区,用于第一次 NSS 调用。如果失败, ERANGE , scratch_buffer_grow被调用,它切换到一个堆缓冲区,并在随后的调用中,分配一个更大的堆缓冲区。 scratch_buffer_free如果有,则释放堆缓冲区。

在您的示例中, tcmalloc 的泄漏报告与暂存缓冲区无关。 (我们在 getaddrinfo 中肯定有这样的错误,特别是在模糊的错误路径上,但当前代码应该大部分都可以。)链接顺序也不是问题,因为很明显, tcmalloc处于事件状态,否则您将不会收到任何泄漏报告。

您看到 tcmalloc 泄漏的原因(但不适用于 valgrind 等其他工具)是 tcmalloc不叫魔法 __libc_freeres函数,这是专门为堆检查器添加的。通常,当进程终止时,glibc 不会释放所有内部分配,因为内核无论如何都会释放该内存。大多数子系统以某种方式在 __libc_freeres 那里注册分配。 .在 getaddrinfo例如,我看到以下仍然分配的资源:
  • 解析结果/etc/resolv.conf (系统 DNS 配置)。
  • 解析结果/etc/nsswitch.conf (NSS 配置)。
  • 由内部 dlopen 产生的各种动态加载器数据结构调用(用于加载 NSS 服务模块。
  • getaddrinfo 中用于记录系统 IPv4/IPv6 支持的缓存.

  • 如果您在 valgrind 下运行示例,您可以使用如下命令轻松查看这些分配:
    valgrind --leak-check=full --show-reachable=yes --run-libc-freeres=no

    关键部分是 --run-libc-freeres=no ,它指示 valgrind 不要调用 __libc_freeres ,默认情况下会这样做。如果省略此参数,valgrind 将不会报告任何内存泄漏。

    关于c - glibc 中的暂存缓冲区是什么意思?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61114952/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com