【问题标题】:Memory leak found with Valgrind but I can't understand itValgrind 发现内存泄漏,但我无法理解
【发布时间】:2016-02-09 08:55:24
【问题描述】:

提前感谢您的关注。我正在为一个项目编写一个模拟程序,但是当我使用 valgrind 时,他的“骨架”出现了释放问题。

程序说明:程序会一直迭代,直到用户使用 SIGINT 或 SIGTERM 停止它。它使用两个线程,一个用于计算(收集器),一个用于处理信号(sighandler)。

一旦其中一个信号到达,程序等待当前迭代完成然后退出。为此,我使用了一个由 sighandler 更改的全局整数(状态),并且收集器在每次迭代结束时进行检查。我使用互斥锁来保护变量。这是代码:

void* sighandler(void *arg);
void* collector(void *arg);

int status = 0;
int counter = 0;
pthread_t t_sighand, t_collector;
pthread_mutex_t mtx_status = PTHREAD_MUTEX_INITIALIZER;
sigset_t set;

int main(int argc, char *argv[]) {
  /* Blocking signals */
  sigemptyset(&set);
  sigaddset(&set, SIGUSR1);
  sigaddset(&set, SIGINT);
  sigaddset(&set, SIGTERM);
  pthread_sigmask(SIG_SETMASK, &set, NULL);

  /* Threads creation */
  pthread_create(&t_sighand, NULL, &sighandler, NULL);
  pthread_create(&t_collector, NULL, &collector, NULL);

  /* Waiting threads to end */
  pthread_join(t_collector, NULL);
  pthread_join(t_sighand, NULL);

  exit(EXIT_SUCCESS);
}

void* sighandler(void *arg) {
  int sig;

  /* Waiting signals */
  while(TRUE) {
    sigwait(&set, &sig);
    if( (sig == SIGINT) || (sig == SIGTERM) )   {
      /* Change of status to notify the signal received */
      pthread_mutex_lock(&mtx_status);
        status = -1;
      pthread_mutex_unlock(&mtx_status);
      pthread_exit(NULL);
    }
  }
}

void* collector(void *arg) {
  while(TRUE)   {
    /* Here I'll do all the stuff */
    /* At the end I check to see if I need to stop */
    pthread_mutex_lock(&mtx_status);
      if(status == -1)  {
        pthread_mutex_unlock(&mtx_status);
        pthread_exit(NULL);
      }
    pthread_mutex_unlock(&mtx_status);

    counter++;
  }
}

当我尝试用 valgrind 运行它时,我得到了这个结果:

==3293== HEAP SUMMARY:
==3293==     in use at exit: 990 bytes in 4 blocks
==3293==   total heap usage: 7 allocs, 3 frees, 1,290 bytes allocated
==3293== 
==3293== LEAK SUMMARY:
==3293==    definitely lost: 0 bytes in 0 blocks
==3293==    indirectly lost: 0 bytes in 0 blocks
==3293==      possibly lost: 0 bytes in 0 blocks
==3293==    still reachable: 990 bytes in 4 blocks
==3293==         suppressed: 0 bytes in 0 blocks
==3293== Rerun with --leak-check=full to see details of leaked memory
==3293== 
==3293== For counts of detected and suppressed errors, rerun with: -v
==3293== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

我发现如果我删除收集器,则不会出现内存泄漏,但我不明白问题可能出在收集器中。你能帮助我吗? :(

再次感谢您的关注和提前帮助!

【问题讨论】:

  • 我没有看到任何泄漏......
  • 我知道操作系统会处理该内存,现在没有问题。但是我仍然想了解为什么 valgrind 看到内存在应该全部释放时仍然可以访问。
  • 总堆使用量:7 次分配,3 次释放,1,290 字节分配 → 看起来它来自这里。我复制/粘贴此代码并使用 valgrind 运行它并得到:总堆使用量:7 分配,7 释放,2,214 字节分配(在向其发送 INT 信号之后)。
  • 技术上你应该pthread_mutex_destroy()你的互斥锁当你完成它。在某些系统上是无操作的,但它可能不在您的系统上。
  • 您确实使用选项 -pthread 而不仅仅是 -lpthread 进行编译,不是吗?

标签: c unix pthreads mutex valgrind


【解决方案1】:

在我尝试过的至少一个系统 (FreeBSD) 上,标准 I/O 缓冲区使用 malloc。特别是,stdout 的缓冲区可以动态分配。直到我在fclose(stdout) main() 完成之前,我才得到一个干净利落的 valgrind 结果。

【讨论】:

    猜你喜欢
    • 2013-02-19
    • 2013-12-17
    • 1970-01-01
    • 2013-06-24
    • 2021-09-29
    • 2011-03-25
    • 2020-03-31
    • 2016-03-15
    • 2014-04-09
    相关资源
    最近更新 更多