valgrind/massif看不到从另一个线程完成的内存交易。

发布于 2025-02-11 12:59:45 字数 4975 浏览 1 评论 0原文

在用Valgrind/massif分析内存使用时,我发现它似乎看不到从另一个线程完成的内存Deallocation,将其报告为泄漏。 这是一个证明:

#include <stdio.h>
#include <iostream>
#include <pthread.h>
#include <stdlib.h>

using namespace std;

struct my_struct
{
  pthread_mutex_t m_mutex;
  void* m_mem;
};

extern "C"
{
  void* my_allocation(void* p)
  {
    my_struct *ptr = (my_struct*)p;
    int error;
    if((error = pthread_mutex_lock(&ptr->m_mutex))) {
      cerr << "mutex lock failed in thread: " << error << endl;
    }
    else {
      ptr->m_mem = malloc(100);
      if((error = pthread_mutex_unlock(&ptr->m_mutex)))
        cerr << "mutex unlock failed in thread: " << error << endl;
    }

    return NULL;
  }

  void* my_deallocation(void* p)
  {
    my_struct *ptr = (my_struct*)p;
    int error;
    if((error = pthread_mutex_lock(&ptr->m_mutex))) {
      cerr << "mutex lock failed in thread: " << error << endl;
    }
    else {
      free(ptr->m_mem);
      ptr->m_mem = NULL;
      if((error = pthread_mutex_unlock(&ptr->m_mutex)))
        cerr << "mutex unlock failed in thread: " << error << endl;
    }

    return NULL;
  }
}

int main(int argc, char **argv)
{
  pthread_t alloc_thread;
  pthread_t dealloc_thread;
  my_struct value;
  value.m_mem = NULL;

  int error;
  if((error = pthread_mutex_init(&value.m_mutex, NULL))) {
    cerr << "Failed to initialize mutex: " << error << endl;
    return 1;
  }

  for(int i=0; i<300; ++i) {
    if((error = pthread_create(&alloc_thread, NULL, my_allocation, &value))) {
      cerr << "Failed to start allocation thread: " << error << endl;
      return 1;
    }

    if((error = pthread_join(alloc_thread, NULL))) {
      cerr << "Failed to join allocation thread: " << error << endl;
      return 1;
    }

    if((error = pthread_mutex_lock(&value.m_mutex))) {
      cerr << "mutex lock failed: " << error << endl;
    }
    else {
      if(!value.m_mem) {
        cerr << "Allocation thread failed to allocate the memory" << endl;
        return 1;
      }
      if((error = pthread_mutex_unlock(&value.m_mutex)))
        cerr << "mutex unlock failed: " << error << endl;
    }

    if((error = pthread_create(&dealloc_thread, NULL, my_deallocation, &value))) {
      cerr << "Failed to start deallocation thread: " << error << endl;
      return 1;
    }

    if((error = pthread_join(dealloc_thread, NULL))) {
      cerr << "Failed to join deallocation thread: " << error << endl;
      return 1;
    }

    if((error = pthread_mutex_lock(&value.m_mutex))) {
      cerr << "mutex lock failed: " << error << endl;
    }
    else {
      if(value.m_mem) {
        cerr << "Deallocation thread failed to deallocate the memory" << endl;
        return 1;
      }
      if((error = pthread_mutex_unlock(&value.m_mutex)))
        cerr << "mutex unlock failed: " << error << endl;
    }
  }

  if((error = pthread_mutex_destroy(&value.m_mutex))) {
    cerr << "Failed to destroy mutex: " << error << endl;
    return 1;
  }

  cout << "Done" << endl;
  return 0;
}

在Valgrind/massif下运行此程序后,我得到的报告似乎表明分配的内存为泄漏。

这是massif报告的片段:

--------------------------------------------------------------------------------
Command:            valgrind-threads
Massif arguments:   --heap=yes --pages-as-heap=yes --massif-out-file=/tmp/valgrind-threads.massif.31220.log
ms_print arguments: /tmp/valgrind-threads.massif.31220.log
--------------------------------------------------------------------------------

100.00% (197,083,136B) (page allocation syscalls) mmap/mremap/brk, --alloc-fns, etc.
->72.36% (142,610,432B) 0x7773FCA: mmap (in /usr/lib64/libc-2.17.so)
| ->68.10% (134,217,728B) 0x76FA2D0: new_heap (in /usr/lib64/libc-2.17.so)
| | ->68.10% (134,217,728B) 0x76FA8D3: arena_get2.isra.3 (in /usr/lib64/libc-2.17.so)
| |   ->68.10% (134,217,728B) 0x770077D: malloc (in /usr/lib64/libc-2.17.so)
| |     ->68.10% (134,217,728B) 0x40C194: my_allocation (valgrind-threads.cpp:24)
| |       ->68.10% (134,217,728B) 0x7466EA4: start_thread (in /usr/lib64/libpthread-2.17.so)
| |         ->68.10% (134,217,728B) 0x7779B0C: clone (in /usr/lib64/libc-2.17.so)
| |           
| ->04.26% (8,392,704B) 0x74677FC: pthread_create@@GLIBC_2.2.5 (in /usr/lib64/libpthread-2.17.so)
| | ->04.26% (8,392,704B) 0x40C384: main (valgrind-threads.cpp:64)
| |   
| ->00.00% (0B) in 1+ places, all below ms_print's threshold (01.00%)

valgrind版本是3.19。 用GCC 4.9.4Red Hat Enterprise Linux服务器版本7.9(Maipo)上构建和运行。

我是错误地阅读报告,还是是valgrind/massif限制,还是我在代码中做错了什么?

While profiling the memory usage with valgrind/massif, I found it does not seem to see the memory deallocation done from another thread, reporting it as a leak.
Here is an program that demonstrates that:

#include <stdio.h>
#include <iostream>
#include <pthread.h>
#include <stdlib.h>

using namespace std;

struct my_struct
{
  pthread_mutex_t m_mutex;
  void* m_mem;
};

extern "C"
{
  void* my_allocation(void* p)
  {
    my_struct *ptr = (my_struct*)p;
    int error;
    if((error = pthread_mutex_lock(&ptr->m_mutex))) {
      cerr << "mutex lock failed in thread: " << error << endl;
    }
    else {
      ptr->m_mem = malloc(100);
      if((error = pthread_mutex_unlock(&ptr->m_mutex)))
        cerr << "mutex unlock failed in thread: " << error << endl;
    }

    return NULL;
  }

  void* my_deallocation(void* p)
  {
    my_struct *ptr = (my_struct*)p;
    int error;
    if((error = pthread_mutex_lock(&ptr->m_mutex))) {
      cerr << "mutex lock failed in thread: " << error << endl;
    }
    else {
      free(ptr->m_mem);
      ptr->m_mem = NULL;
      if((error = pthread_mutex_unlock(&ptr->m_mutex)))
        cerr << "mutex unlock failed in thread: " << error << endl;
    }

    return NULL;
  }
}

int main(int argc, char **argv)
{
  pthread_t alloc_thread;
  pthread_t dealloc_thread;
  my_struct value;
  value.m_mem = NULL;

  int error;
  if((error = pthread_mutex_init(&value.m_mutex, NULL))) {
    cerr << "Failed to initialize mutex: " << error << endl;
    return 1;
  }

  for(int i=0; i<300; ++i) {
    if((error = pthread_create(&alloc_thread, NULL, my_allocation, &value))) {
      cerr << "Failed to start allocation thread: " << error << endl;
      return 1;
    }

    if((error = pthread_join(alloc_thread, NULL))) {
      cerr << "Failed to join allocation thread: " << error << endl;
      return 1;
    }

    if((error = pthread_mutex_lock(&value.m_mutex))) {
      cerr << "mutex lock failed: " << error << endl;
    }
    else {
      if(!value.m_mem) {
        cerr << "Allocation thread failed to allocate the memory" << endl;
        return 1;
      }
      if((error = pthread_mutex_unlock(&value.m_mutex)))
        cerr << "mutex unlock failed: " << error << endl;
    }

    if((error = pthread_create(&dealloc_thread, NULL, my_deallocation, &value))) {
      cerr << "Failed to start deallocation thread: " << error << endl;
      return 1;
    }

    if((error = pthread_join(dealloc_thread, NULL))) {
      cerr << "Failed to join deallocation thread: " << error << endl;
      return 1;
    }

    if((error = pthread_mutex_lock(&value.m_mutex))) {
      cerr << "mutex lock failed: " << error << endl;
    }
    else {
      if(value.m_mem) {
        cerr << "Deallocation thread failed to deallocate the memory" << endl;
        return 1;
      }
      if((error = pthread_mutex_unlock(&value.m_mutex)))
        cerr << "mutex unlock failed: " << error << endl;
    }
  }

  if((error = pthread_mutex_destroy(&value.m_mutex))) {
    cerr << "Failed to destroy mutex: " << error << endl;
    return 1;
  }

  cout << "Done" << endl;
  return 0;
}

After running this program under valgrind/massif, I am getting the report that seems to indicate the allocated memory as leaked.

Here is a fragment of massif report:

--------------------------------------------------------------------------------
Command:            valgrind-threads
Massif arguments:   --heap=yes --pages-as-heap=yes --massif-out-file=/tmp/valgrind-threads.massif.31220.log
ms_print arguments: /tmp/valgrind-threads.massif.31220.log
--------------------------------------------------------------------------------

100.00% (197,083,136B) (page allocation syscalls) mmap/mremap/brk, --alloc-fns, etc.
->72.36% (142,610,432B) 0x7773FCA: mmap (in /usr/lib64/libc-2.17.so)
| ->68.10% (134,217,728B) 0x76FA2D0: new_heap (in /usr/lib64/libc-2.17.so)
| | ->68.10% (134,217,728B) 0x76FA8D3: arena_get2.isra.3 (in /usr/lib64/libc-2.17.so)
| |   ->68.10% (134,217,728B) 0x770077D: malloc (in /usr/lib64/libc-2.17.so)
| |     ->68.10% (134,217,728B) 0x40C194: my_allocation (valgrind-threads.cpp:24)
| |       ->68.10% (134,217,728B) 0x7466EA4: start_thread (in /usr/lib64/libpthread-2.17.so)
| |         ->68.10% (134,217,728B) 0x7779B0C: clone (in /usr/lib64/libc-2.17.so)
| |           
| ->04.26% (8,392,704B) 0x74677FC: pthread_create@@GLIBC_2.2.5 (in /usr/lib64/libpthread-2.17.so)
| | ->04.26% (8,392,704B) 0x40C384: main (valgrind-threads.cpp:64)
| |   
| ->00.00% (0B) in 1+ places, all below ms_print's threshold (01.00%)

Valgrind version is 3.19.
Building and running that with gcc 4.9.4 on Red Hat Enterprise Linux Server release 7.9 (Maipo).

Am I reading the report incorrectly, or it is a valgrind/massif limitation, or I am doing something wrong in the code?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

过期情话 2025-02-18 12:59:45

正如它在另一个问题< /a>我发布了有关valgrind/massif未跟踪的TLS Deleclations:

如果我们使用-pages-as-as-heap,Valgrind/massif将报告每个线程Malloc Cache分配的GLIBC内存页面,至少在线程上的第一个分配时(有时在需要生长时可能会发生重新分配)。
这给人以分配的内存泄漏的印象。

如果没有运行 - 页面选项,则正确解释了交易。

As it was found in another question I posted about TLS deallocations not tracked by valgrind/massif:

If we use --pages-as-heap, valgrind/massif will report the GLIBC memory pages allocated per thread malloc cache, which happens at least at the first allocation on thread (sometimes the reallocations may happen when heap needs to grow).
This gives an impression the allocated memory has leaked.

If run without --pages-as-heap option, the deallocations are accounted for correctly.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文