使用valgrind检测glib内存泄漏:自带supp未生效,自定义supp是否掩盖代码问题?
问题解答
一、你的自定义抑制文件确实可能掩盖自身代码问题
从Valgrind的调用栈来看,这个64字节的still reachable泄漏,触发路径是你的代码调用g_dbus_connection_signal_subscribe后产生的。g_dbus_connection_signal_subscribe会返回一个订阅ID,你必须在不再需要订阅时调用g_dbus_connection_signal_unsubscribe来释放相关内存。
你的自定义抑制文件直接匹配libgio-2.0.so、libglib-2.0.so等库的所有泄漏,这会把库本身的正常泄漏和你代码未正确释放订阅导致的泄漏一起屏蔽掉。如果是你忘记调用取消订阅的函数,那这个泄漏本质是你的代码问题,却被抑制文件掩盖了。
建议先排查:
- 检查
setup_signal_subscribers函数中,是否保存了g_dbus_connection_signal_subscribe返回的订阅ID; - 在程序退出或适配器销毁时(比如
binc_adapter_create对应的销毁函数),是否调用了g_dbus_connection_signal_unsubscribe释放所有订阅。
二、系统自带glib.supp未抑制该泄漏的可能原因
系统的glib.supp文件是glib官方维护的抑制规则,它不会笼统屏蔽整个库的所有泄漏,而是针对glib已知的、正常的、无法避免的内存泄漏(比如全局初始化的单例内存,程序退出时才会释放)做精确匹配。这个泄漏没被抑制,可能有以下原因:
- 版本差异:你使用的glib/gio版本(2.74.6)中存在这个特定的泄漏,而系统自带的
glib.supp文件版本较旧,还没添加对应的抑制规则; - 规则精度:系统supp文件的规则是针对特定函数调用链的,而这个泄漏的调用路径(
g_memdup2-> 未知函数 ->g_dbus_connection_signal_subscribe)不在现有规则的匹配范围内; - 泄漏类型判断:
still reachable类型的泄漏,glib官方认为如果是用户代码未正确调用API释放的,不属于库的问题,所以不会添加到默认抑制文件中——毕竟这个内存是可以通过正确调用API释放的,不是库本身的固有泄漏。
内容的提问来源于stack exchange,提问作者abqjln
相关产品推荐
相关产品推荐

