繁体   English   中英

glib:valgrind 在 g_strsplit 之后报告“仍可访问”块

[英]glib: valgrind reporting 'still reachable' blocks after g_strsplit

我有一段非常简单的代码:

#include <stdio.h>
#include <glib.h>

int main(int argc, char * argv[])
{
  const char * path = "/a/b/c/d/e/f/g/h/";
  gchar ** parts = NULL;
  int i;

  parts = g_strsplit( (const gchar *) path, "/", 0 );

  for ( i = 0; parts[i]; i++ ) {
    if (parts[i][0] == '\0') {
      continue;
    }
    printf("part: %s\n", parts[i]);
  }

  g_strfreev( parts );
  return 0;
}

然而,当我通过 Valgrind 运行这段代码时,我得到了一堆“仍然可以到达”的块:

==12924== 
==12924== HEAP SUMMARY:
==12924==     in use at exit: 4,252 bytes in 8 blocks
==12924==   total heap usage: 19 allocs, 11 frees, 4,358 bytes allocated
==12924== 
==12924== 240 bytes in 1 blocks are still reachable in loss record 1 of 6
==12924==    at 0x4A04820: memalign (vg_replace_malloc.c:581)
==12924==    by 0x4A048D7: posix_memalign (vg_replace_malloc.c:709)
==12924==    by 0x36A8255F87: ??? (in /lib64/libglib-2.0.so.0.2200.5)
==12924==    by 0x36A825680B: g_slice_alloc (in /lib64/libglib-2.0.so.0.2200.5)
==12924==    by 0x36A8257DBD: g_slist_prepend (in /lib64/libglib-2.0.so.0.2200.5)
==12924==    by 0x36A825AB15: g_strsplit (in /lib64/libglib-2.0.so.0.2200.5)
==12924==    by 0x4005C8: main (strsplit.c:10)
==12924== 
==12924== 252 bytes in 1 blocks are still reachable in loss record 2 of 6
==12924==    at 0x4A04A28: calloc (vg_replace_malloc.c:467)
==12924==    by 0x36A8241707: g_malloc0 (in /lib64/libglib-2.0.so.0.2200.5)
==12924==    by 0x36A8255742: ??? (in /lib64/libglib-2.0.so.0.2200.5)
==12924==    by 0x36A825669D: g_slice_alloc (in /lib64/libglib-2.0.so.0.2200.5)
==12924==    by 0x36A8257DBD: g_slist_prepend (in /lib64/libglib-2.0.so.0.2200.5)
==12924==    by 0x36A825AB15: g_strsplit (in /lib64/libglib-2.0.so.0.2200.5)
==12924==    by 0x4005C8: main (strsplit.c:10)
==12924== 
==12924== 504 bytes in 1 blocks are still reachable in loss record 3 of 6
==12924==    at 0x4A04A28: calloc (vg_replace_malloc.c:467)
==12924==    by 0x36A8241707: g_malloc0 (in /lib64/libglib-2.0.so.0.2200.5)
==12924==    by 0x36A8255722: ??? (in /lib64/libglib-2.0.so.0.2200.5)
==12924==    by 0x36A825669D: g_slice_alloc (in /lib64/libglib-2.0.so.0.2200.5)
==12924==    by 0x36A8257DBD: g_slist_prepend (in /lib64/libglib-2.0.so.0.2200.5)
==12924==    by 0x36A825AB15: g_strsplit (in /lib64/libglib-2.0.so.0.2200.5)
==12924==    by 0x4005C8: main (strsplit.c:10)
==12924== 
==12924== 504 bytes in 1 blocks are still reachable in loss record 4 of 6
==12924==    at 0x4A04A28: calloc (vg_replace_malloc.c:467)
==12924==    by 0x36A8241707: g_malloc0 (in /lib64/libglib-2.0.so.0.2200.5)
==12924==    by 0x36A825578B: ??? (in /lib64/libglib-2.0.so.0.2200.5)
==12924==    by 0x36A825669D: g_slice_alloc (in /lib64/libglib-2.0.so.0.2200.5)
==12924==    by 0x36A8257DBD: g_slist_prepend (in /lib64/libglib-2.0.so.0.2200.5)
==12924==    by 0x36A825AB15: g_strsplit (in /lib64/libglib-2.0.so.0.2200.5)
==12924==    by 0x4005C8: main (strsplit.c:10)
==12924== 
==12924== 720 bytes in 3 blocks are still reachable in loss record 5 of 6
==12924==    at 0x4A04820: memalign (vg_replace_malloc.c:581)
==12924==    by 0x4A048D7: posix_memalign (vg_replace_malloc.c:709)
==12924==    by 0x36A8255F87: ??? (in /lib64/libglib-2.0.so.0.2200.5)
==12924==    by 0x36A8256841: g_slice_alloc (in /lib64/libglib-2.0.so.0.2200.5)
==12924==    by 0x36A8257DBD: g_slist_prepend (in /lib64/libglib-2.0.so.0.2200.5)
==12924==    by 0x36A825AB15: g_strsplit (in /lib64/libglib-2.0.so.0.2200.5)
==12924==    by 0x4005C8: main (strsplit.c:10)
==12924== 
==12924== 2,032 bytes in 1 blocks are still reachable in loss record 6 of 6
==12924==    at 0x4A04A28: calloc (vg_replace_malloc.c:467)
==12924==    by 0x36A8241707: g_malloc0 (in /lib64/libglib-2.0.so.0.2200.5)
==12924==    by 0x36A8256642: g_slice_alloc (in /lib64/libglib-2.0.so.0.2200.5)
==12924==    by 0x36A8257DBD: g_slist_prepend (in /lib64/libglib-2.0.so.0.2200.5)
==12924==    by 0x36A825AB15: g_strsplit (in /lib64/libglib-2.0.so.0.2200.5)
==12924==    by 0x4005C8: main (strsplit.c:10)
==12924== 
==12924== LEAK SUMMARY:
==12924==    definitely lost: 0 bytes in 0 blocks
==12924==    indirectly lost: 0 bytes in 0 blocks
==12924==      possibly lost: 0 bytes in 0 blocks
==12924==    still reachable: 4,252 bytes in 8 blocks
==12924==         suppressed: 0 bytes in 0 blocks
==12924== 
==12924== For counts of detected and suppressed errors, rerun with: -v
==12924== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 6)

我的问题是:我是不是没有正确清理或者这些错误是可以安全忽略的?

谢谢!

valgrind 文档中,

因为存在不同严重程度的不同类型的泄漏,一个有趣的问题是:哪些泄漏应该算作真正的“错误”,哪些不应该算作真正的“错误”?

绝对丢失和可能丢失的块被视为真正的“错误”。 间接丢失但仍可到达的块不计为真正的“错误”,即使指定了 --show-reachable=yes 并打印了它们; 这是因为这样的块不需要程序员直接修复。

所以你可以放心地忽略这些错误,因为这些块无论如何都会在程序退出时被回收。

另请阅读此 SO 线程,其中详细讨论了 Valgrind memory 错误

Valgrind 检测到的 Still Reachable Leak

本文档可能有助于了解 Valgrind/memcheck 检测到哪种类型的泄漏。

至于问题本身,首先不要使用 GLib 中的默认切片分配器在基于 GLib 的程序上运行 valgrind,因为这会在 valgrind 日志中产生大量“垃圾”output。 只需运行指示 GLib 使用普通 mallocs 的程序:

$ G_DEBUG=always-malloc valgrind --leak-check=full --show-reachable=yes your-program your-args
Program received signal SIGSEGV, Segmentation fault.

 in g_slice_alloc () from /usr/local/lib/libglib-2.0.so.0

(gdb) backtrace
 in g_slice_alloc () from /usr/local/lib/libglib-2.0.so.0
 in g_slist_prepend () from /usr/local/lib/libglib-2.0.so.0
 in g_strsplit () from /usr/local/lib/libglib-2.0.so.0

猜猜,glib 中的分配有问题。 许多其他使用 Glib 的项目也有这样的问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM