在Glib / GDBus代码中获取内存泄漏? [英] Getting memory leaks in Glib/GDBus code?

查看:708
本文介绍了在Glib / GDBus代码中获取内存泄漏?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


$ b

  method_call_message = g_dbus_message_new_method_call(owner,$ b) $ b 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); 

我假设这会计划BOTH method_call_message gv 用于GC?

GC何时完成?



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



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

解决方案

使用一些Valgrind魔法:

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

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

<$ p 0x4A06A2E处的$ p> :malloc(vg_replace_malloc.c:270)
== 20088 == by 0x3F21E503B6:g_malloc(位于/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:??? (在/usr/lib64/libglib-2.0.so.0.4400.1)
== 20088 == by 0x3F21E7FA61:??? (位于/usr/lib64/libglib-2.0.so.0.4400.1)
== 20088 == by 0x3F21E80348:g_variant_get_va(位于/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:??? (位于/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:??? (在/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)); / *复制字符串* /
g_free(tmp); / * free g_strdup分配空间* /

调用 g_free(。 ..) 释放分配的存储空间。



现在我得到:

<$ p
== 6472 ==绝对丢失:0字节0块
== 6472 ==间接丢失:0字节0块
== 6472 ==可能丢失:148块中的9,841字节
== 6472 ==仍然可达:986块中的106,376字节
== 6472 ==被抑制:0字节0块


I'm using GDBus (via Glib) and I have code like:

  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);

I assume method_call_message is now a container for gv.

Before exiting I call:

 g_object_unref(method_call_message);

I assume this will then schedule BOTH method_call_message and gv for GC?

When is GC done?

I appear to be leaking some 4 bytes at a time as I watch the top updates on VIRT memory.

I have commented out pieces of code till I localized it (the leak) to my GDBus calls.

解决方案

Using some Valgrind magic:

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

I was able to winnow out the memory management obfuscation and get to a call-stack that showed the problem. The Valgrind output indicated that all my memory losses were associated with calls to 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)

Obviously the call to g_variant_get(...) begats a call to g_strdup(...) (if your format_string includes an 's' for string). So, in my case, the code is:

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 */

And a call to g_free(...) frees the allocated storage.

Now I get:

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

这篇关于在Glib / GDBus代码中获取内存泄漏?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆