在Glib / GDBus代码中导致内存泄漏?

时间:2017-03-23 21:10:02

标签: garbage-collection glib

我使用GDBus(通过Glib),我的代码如下:

  method_call_message = g_dbus_message_new_method_call(owner,
                                                       OBJECT_PATH,
                                                       INTERFACE_NAME,
                                                       "get_snmpv2_mib");

  GVariant *gv = g_variant_new("(sissi)", ip, port, mib, variable, instance);

  g_dbus_message_set_body(method_call_message, gv);

我假设 method_call_message 现在是 gv 的容器。

退出前我打电话:

 g_object_unref(method_call_message);

我认为这会为GC安排 method_call_message gv 吗?

GC什么时候完成?

当我在VIRT内存上观看顶部更新时,我似乎一次泄漏了大约4个字节。

我已经注释掉了一些代码,直到我将它(泄漏)本地化为我的GDBus调用。

1 个答案:

答案 0 :(得分:1)

使用一些Valgrind魔法:

libtool exec valgrind --tool=memcheck --leak-check=full --log-file=w <executable + args>

我能够清除内存管理混淆并进入显示问题的调用堆栈。 Valgrind输出表明我所有的内存损失都与调用 g_variant_get(...) 相关联:

at 0x4A06A2E: malloc (vg_replace_malloc.c:270)
==20088==    by 0x3F21E503B6: g_malloc (in /usr/lib64/libglib-2.0.so.0.4400.1)
==20088==    by 0x3F21E6860D: g_strdup (in /usr/lib64/libglib-2.0.so.0.4400.1)
==20088==    by 0x3F21E7FD01: ??? (in /usr/lib64/libglib-2.0.so.0.4400.1)
==20088==    by 0x3F21E7FA61: ??? (in /usr/lib64/libglib-2.0.so.0.4400.1)
==20088==    by 0x3F21E80348: g_variant_get_va (in /usr/lib64/libglib-2.0.so.0.4400.1)
==20088==    by 0x3F21E80585: g_variant_get (in /usr/lib64/libglib-2.0.so.0.4400.1)
==20088==    by 0x4C30555: server_gvariant (in /usr/lib64/libdrsnvc.so)
==20088==    by 0x40257B: NVCtimerCB(void*) (main.cc:73)
==20088==    by 0x3F21E48C3A: ??? (in /usr/lib64/libglib-2.0.so.0.4400.1)
==20088==    by 0x3F21E48519: g_main_context_dispatch (in /usr/lib64/libglib-2.0.so.0.4400.1)
==20088==    by 0x3F21E4A5A7: ??? (in /usr/lib64/libglib-2.0.so.0.4400.1)

显然,对 g_variant_get(...) 的调用会致电 g_strdup(...) (如果 format_string 包含字符串's')。所以,就我而言,代码是:

g_variant_get(response, "(isi)", &od.stat, &od.msg, &od.i);
gchar *tmp = od.msg;
od.msg = strncpy(msg, od.msg, strlen(od.msg)); /* copy string */
g_free(tmp); /* free g_strdup allocated space */

拨打 g_free(...) 可以释放已分配的存储空间。

现在我明白了:

LEAK SUMMARY:
==6472==    definitely lost: 0 bytes in 0 blocks
==6472==    indirectly lost: 0 bytes in 0 blocks
==6472==      possibly lost: 9,841 bytes in 148 blocks
==6472==    still reachable: 106,376 bytes in 986 blocks
==6472==         suppressed: 0 bytes in 0 blocks