OpenMP并行区域可能导致Valgrind中的内存泄漏

时间:2018-06-20 00:18:05

标签: openmp valgrind

似乎有一些现存的问题(例如Memory Leak - OpenMP)在讨论这个问题,但这些答案似乎都没有直接的权威性或对实际解决问题有用。

我在一个较大的项目中有一个特定的代码块,如下所示:

#pragma omp parallel
  {
    #pragma omp single
    {
        some_function();
    }
  }

(注意:我在some_function中有omp任务指令,但Valgrind并没有指责它们。)
当我的C ++项目在Valgrind下使用以下命令编译时:

 valgrind --verbose --num-callers=30 --track-fds=yes --show-reachable=yes --leak-check=full --show-leak-kinds=all ./main

我获得:

==1189== HEAP SUMMARY:
==1189==     in use at exit: 86,032 bytes in 29 blocks
==1189==   total heap usage: 11,637,948 allocs, 11,637,919 frees, 1,202,339,183 bytes allocated
==1189==
==1189== Searching for pointers to 29 not-freed blocks
==1189== Checked 193,061,216 bytes
==1189==
==1189== 8 bytes in 1 blocks are still reachable in loss record 1 of 7
==1189==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==1189==    by 0x54CD778: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==1189==    by 0x54D6647: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==1189==    by 0x54CBDE1: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==1189==    by 0x40106B9: call_init.part.0 (dl-init.c:72)
==1189==    by 0x40107CA: call_init (dl-init.c:30)
==1189==    by 0x40107CA: _dl_init (dl-init.c:120)
==1189==    by 0x4000C69: ??? (in /lib/x86_64-linux-gnu/ld-2.23.so)
==1189==
==1189== 176 bytes in 1 blocks are still reachable in loss record 2 of 7
==1189==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==1189==    by 0x54CD778: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==1189==    by 0x54D5A3A: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==1189==    by 0x54CD9DC: omp_set_num_threads (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==1189==    by 0x4024C1: main (main.cpp:660)
==1189==
==1189== 192 bytes in 1 blocks are still reachable in loss record 3 of 7
==1189==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==1189==    by 0x54CD778: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==1189==    by 0x54D4ECA: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==1189==    by 0x54D0CB9: GOMP_parallel (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==1189==    by 0x409581: par_randomized_mst_priority_cw(int, std::vector<Edge, std::allocator<Edge> >&, std::vector<int, std::allocator<int> >&, bool) (mst.h:152)
==1189==    by 0x40A73F: task2B_1() (main.cpp:355)
==1189==    by 0x40267C: main (main.cpp:678)
==1189==
==1189== 200 bytes in 1 blocks are still reachable in loss record 4 of 7
==1189==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==1189==    by 0x4C2FDEF: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==1189==    by 0x54CD7C8: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==1189==    by 0x54D541A: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==1189==    by 0x54D0CB9: GOMP_parallel (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==1189==    by 0x409581: par_randomized_mst_priority_cw(int, std::vector<Edge, std::allocator<Edge> >&, std::vector<int, std::allocator<int> >&, bool) (mst.h:152)
==1189==    by 0x40A73F: task2B_1() (main.cpp:355)
==1189==    by 0x40267C: main (main.cpp:678)
==1189==
==1189== 5,760 bytes in 1 blocks are still reachable in loss record 5 of 7
==1189==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==1189==    by 0x54CD778: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==1189==    by 0x54D4489: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==1189==    by 0x54D0CA5: GOMP_parallel (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==1189==    by 0x407D5A: par_simulate_priority_cw_using_radix_sort(int, std::vector<Edge, std::allocator<Edge> >&, std::vector<int, std::allocator<int> >&) (mst.h:52)
==1189==    by 0x409C35: par_randomized_mst_priority_cw(int, std::vector<Edge, std::allocator<Edge> >&, std::vector<int, std::allocator<int> >&, bool) (mst.h:203)
==1189==    by 0x40A73F: task2B_1() (main.cpp:355)
==1189==    by 0x40267C: main (main.cpp:678)
==1189==
==1189== 6,992 bytes in 23 blocks are possibly lost in loss record 6 of 7
==1189==    at 0x4C2FB55: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==1189==    by 0x40138A4: allocate_dtv (dl-tls.c:322)
==1189==    by 0x40138A4: _dl_allocate_tls (dl-tls.c:539)
==1189==    by 0x5ED326E: allocate_stack (allocatestack.c:588)
==1189==    by 0x5ED326E: pthread_create@@GLIBC_2.2.5 (pthread_create.c:539)
==1189==    by 0x54D499F: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==1189==    by 0x54D0CB9: GOMP_parallel (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==1189==    by 0x409581: par_randomized_mst_priority_cw(int, std::vector<Edge, std::allocator<Edge> >&, std::vector<int, std::allocator<int> >&, bool) (mst.h:152)
==1189==    by 0x40A73F: task2B_1() (main.cpp:355)
==1189==    by 0x40267C: main (main.cpp:678)
==1189==
==1189== 72,704 bytes in 1 blocks are still reachable in loss record 7 of 7
==1189==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==1189==    by 0x4EC3EFF: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==1189==    by 0x40106B9: call_init.part.0 (dl-init.c:72)
==1189==    by 0x40107CA: call_init (dl-init.c:30)
==1189==    by 0x40107CA: _dl_init (dl-init.c:120)
==1189==    by 0x4000C69: ??? (in /lib/x86_64-linux-gnu/ld-2.23.so)
==1189==
==1189== LEAK SUMMARY:
==1189==    definitely lost: 0 bytes in 0 blocks
==1189==    indirectly lost: 0 bytes in 0 blocks
==1189==      possibly lost: 6,992 bytes in 23 blocks
==1189==    still reachable: 79,040 bytes in 6 blocks
==1189==         suppressed: 0 bytes in 0 blocks
==1189==
==1189== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
==1189== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

我知道尚未释放的可访问内存并不是真正的错误。但是,泄漏之一是23个内存块,它们可能在并行指令中丢失。特别是:

==1189== 6,992 bytes in 23 blocks are possibly lost in loss record 6 of 7
==1189==    at 0x4C2FB55: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==1189==    by 0x40138A4: allocate_dtv (dl-tls.c:322)
==1189==    by 0x40138A4: _dl_allocate_tls (dl-tls.c:539)
==1189==    by 0x5ED326E: allocate_stack (allocatestack.c:588)
==1189==    by 0x5ED326E: pthread_create@@GLIBC_2.2.5 (pthread_create.c:539)
==1189==    by 0x54D499F: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==1189==    by 0x54D0CB9: GOMP_parallel (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==1189==    by 0x409581: par_randomized_mst_priority_cw(int, std::vector<Edge, std::allocator<Edge> >&, std::vector<int, std::allocator<int> >&, bool) (mst.h:152)
==1189==    by 0x40A73F: task2B_1() (main.cpp:355)
==1189==    by 0x40267C: main (main.cpp:678)

来自我提供的代码示例。特别地,mst.h:152实际上是#pragma omp parallel,因此该行以某种方式导致泄漏。如果有必要,我可以提供更多代码,但是我不确定这是否会有所帮助,因为我直觉这是OpenMP一端的错误,在该错误中,无法根据内存分配对创建的线程进行适当的管理。使用OpenMP时,我应该期待这一点吗?我需要警惕一些陷阱,这可能会导致这种情况吗?

我应该提到的是,删除此块中的并行区域会使泄漏消失,所以问题出在这里(可能是?),但是我如何确定?除了到目前为止我还没有做的事情之外,还有没有更果断的程序来跟踪我的代码中负责泄漏的部分?

0 个答案:

没有答案