valgrind 在测试程序中使用时不报告函数中的内存泄漏

问题描述 投票:0回答:1

我正在低于 valgrind 报告的内存泄漏。

==51== 200 bytes in 1 blocks are definitely lost in loss record 348 of 417
==51==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==51==    by 0x508CF54: __libc_alloc_buffer_allocate (alloc_buffer_allocate.c:26)
==51==    by 0x5130628: alloc_buffer_allocate (alloc_buffer.h:143)
==51==    by 0x5130628: __resolv_conf_allocate (resolv_conf.c:411)
==51==    by 0x512DE21: __resolv_conf_load (res_init.c:592)
==51==    by 0x5130232: __resolv_conf_get_current (resolv_conf.c:163)
==51==    by 0x512E3D4: __res_vinit (res_init.c:614)
==51==    by 0x512F5CF: maybe_init (resolv_context.c:122)
==51==    by 0x512F5CF: context_get (resolv_context.c:184)
==51==    by 0x512F5CF: context_get (resolv_context.c:176)
==51==    by 0x512F5CF: __resolv_context_get (resolv_context.c:195)
==51==    by 0x511E63F: gethostbyname (getXXbyYY.c:105)
==51==    by 0x153745: getinterfaceip (sctpThread.cpp:72)
==51==    by 0x153745: startPrometheus(sctp_params&) (sctpThread.cpp:539)
==51==    by 0x145051: main (sctpThread.cpp:608)
==51== 

紧随其后的是报告来源的源代码

char* getinterfaceip()
{
   char hostname[256];
   char *IP;
   struct hostent *host_entry;
   int retVal;
   retVal = gethostname(hostname, sizeof(hostname));
   if ( retVal == -1 )
       return NULL;
   host_entry = gethostbyname(hostname);
   if ( host_entry == NULL )
       return NULL;
   IP = inet_ntoa(*((struct in_addr*) host_entry->h_addr_list[0]));
   return IP;
}

void startPrometheus(sctp_params_t &sctpParams) {
    auto podName = std::getenv("POD_NAME");
    string metric = "E2TBeta";
    if (strstr(podName, "alpha") != NULL) {
        metric = "E2TAlpha";
    }
    //Get eth0 interface IP
    char* host = getinterfaceip();
    string hostip = host;

    sctpParams.prometheusFamily = &BuildCounter()
            .Name(metric.c_str())
            .Help("E2T instance metrics")
            .Labels({{"POD_NAME", sctpParams.podName}})
            .Register(*sctpParams.prometheusRegistry);

    string prometheusPath;
    if (hostip.empty())
        prometheusPath = sctpParams.prometheusPort + "," + "[::]:" + sctpParams.prometheusPort;
}

但是如果我在我的简单 c 程序中使用相同的 getinterfaceip() 函数,如下所示,并尝试使用 valgrind,它不会报告任何泄漏。这是否意味着内存泄漏不在报告的 getinterfaceip() 函数中?

#include<stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
#include <sys/time.h>
#include <sys/inotify.h>
#include <errno.h>
#include <sys/stat.h>
#include <arpa/inet.h>
#include <netdb.h>

main()
{
   char hostname[256];
   char *IP;
   struct hostent *host_entry;
   int retVal;
   retVal = gethostname(hostname, sizeof(hostname));
   if ( retVal == -1 )
       return NULL;
   host_entry = gethostbyname(hostname);
   if ( host_entry == NULL )
       return NULL;
   IP = inet_ntoa(*((struct in_addr*) host_entry->h_addr_list[0]));
   printf("%s", IP);
   sleep(300);
}
c memory-leaks valgrind
1个回答
0
投票

你没有说你使用的是哪个操作系统、CPU 或编译器。所以我猜Linux amd64 GCC。

这可能是一个 GNU libc 错误。

GNU libc 有一个函数,__libc_freeres(),Valgrind 在 clean 退出时调用它来像这样释放内存。像这样的泄漏意味着以下之一

  1. 你的 Valgrind 版本太旧了
  2. 您使用的系统没有 __libc_freeres
  3. Valgrind 无法定位和调用 __libc_freeres
  4. GNU libc 更改为添加 _libc_freeres 中缺少的分配,换句话说,GNU libc 中的错误

您可以通过使用

-v -v
(详细标志堆栈)运行 Valgrind 来测试它是否是前三点之一。

你应该看到

--2474793-- Caught __NR_exit; running __gnu_cxx::__freeres and __libc_freeres() wrapper

(PID很可能会不同)

© www.soinside.com 2019 - 2024. All rights reserved.