memory leaks after linking libnotify
After writing my program using libnotify
to display notifications, I realized that valgrind
reports memory leaks in my program. After reducing the program to a small file I figured out, that libnotify
is the problem. But see for yourself:
#include <libnotify/notify.h>
#include <stdlib.h>
int main() {
/* notify_init ("Hello world!"); */
/* NotifyNotification * Hello = notify_notification_new ("Hello world", "This is an example notification.", "dialog-information"); */
/* notify_notification_show (Hello, NULL); */
/* g_object_unref(G_OBJECT(Hello)); */
/* notify_uninit(); */
return 0;
}
(the commented code is from the archwiki site on Desktop notifications)
compiled as cc -g -o mwe
pkg-config --cflags --libs libnotify mwe.c
and
executed as valgrind --tool=memcheck --leak-check=full ./mwe
prints
$ valgrind --tool=memcheck --leak-check=full ./mwe
==106763== Memcheck, a memory error detector
==106763== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==106763== Using Valgrind-3.16.1 and LibVEX; rerun with -h for copyright info
==106763== Command: ./mwe
==106763==
==106763==
==106763== HEAP SUMMARY:
==106763== in use at exit: 36,860 bytes in 232 blocks
==106763== total heap usage: 288 allocs, 56 frees, 45,284 bytes allocated
==106763==
==106763== 16 bytes in 1 blocks are possibly lost in loss record 89 of 232
==106763== at 0x483CB65: calloc (vg_replace_malloc.c:760)
==106763== by 0x4B0B941: g_malloc0 (in /usr/lib/libglib-2.0.so.0.6600.0)
==106763== by 0x4A95117: ??? (in /usr/lib/libgobject-2.0.so.0.6600.0)
==106763== by 0x4A9583F: g_type_register_fundamental (in /usr/lib/libgobject-2.0.so.0.6600.0)
==106763== by 0x4A72755: ??? (in /usr/lib/libgobject-2.0.so.0.6600.0)
==106763== by 0x40112DD: call_init.part.0 (in /usr/lib/ld-2.32.so)
==106763== by 0x40113C7: _dl_init (in /usr/lib/ld-2.32.so)
==106763== by 0x40020C9: ??? (in /usr/lib/ld-2.32.so)
==106763==
==106763== 16 bytes in 1 blocks are possibly lost in loss record 90 of 232
==106763== at 0x483A6AF: malloc (vg_replace_malloc.c:306)
==106763== by 0x4B0CA68: g_realloc (in /usr/lib/libglib-2.0.so.0.6600.0)
==106763== by 0x4A9509D: ??? (in /usr/lib/libgobject-2.0.so.0.6600.0)
==106763== by 0x4A9583F: g_type_register_fundamental (in /usr/lib/libgobject-2.0.so.0.6600.0)
==106763== by 0x4A72755: ??? (in /usr/lib/libgobject-2.0.so.0.6600.0)
==106763== by 0x40112DD: call_init.part.0 (in /usr/lib/ld-2.32.so)
==106763== by 0x40113C7: _dl_init (in /usr/lib/ld-2.32.so)
==106763== by 0x40020C9: ??? (in /usr/lib/ld-2.32.so)
==106763==
==106763== 16 bytes in 1 blocks are possibly lost in loss record 91 of 232
==106763== at 0x483CB65: calloc (vg_replace_malloc.c:760)
==106763== by 0x4B0B941: g_malloc0 (in /usr/lib/libglib-2.0.so.0.6600.0)
==106763== by 0x4A95117: ??? (in /usr/lib/libgobject-2.0.so.0.6600.0)
==106763== by 0x4A9583F: g_type_register_fundamental (in /usr/lib/libgobject-2.0.so.0.6600.0)
==106763== by 0x4A727B4: ??? (in /usr/lib/libgobject-2.0.so.0.6600.0)
==106763== by 0x40112DD: call_init.part.0 (in /usr/lib/ld-2.32.so)
==106763== by 0x40113C7: _dl_init (in /usr/lib/ld-2.32.so)
==106763== by 0x40020C9: ??? (in /usr/lib/ld-2.32.so)
==106763==
==106763== 16 bytes in 1 blocks are possibly lost in loss record 92 of 232
==106763== at 0x483A6AF: malloc (vg_replace_malloc.c:306)
==106763== by 0x4B0CA68: g_realloc (in /usr/lib/libglib-2.0.so.0.6600.0)
==106763== by 0x4A9509D: ??? (in /usr/lib/libgobject-2.0.so.0.6600.0)
==106763== by 0x4A9583F: g_type_register_fundamental (in /usr/lib/libgobject-2.0.so.0.6600.0)
==106763== by 0x4A727B4: ??? (in /usr/lib/libgobject-2.0.so.0.6600.0)
==106763== by 0x40112DD: call_init.part.0 (in /usr/lib/ld-2.32.so)
==106763== by 0x40113C7: _dl_init (in /usr/lib/ld-2.32.so)
==106763== by 0x40020C9: ??? (in /usr/lib/ld-2.32.so)
==106763==
==106763== 16 bytes in 1 blocks are possibly lost in loss record 93 of 232
==106763== at 0x483CB65: calloc (vg_replace_malloc.c:760)
==106763== by 0x4B0B941: g_malloc0 (in /usr/lib/libglib-2.0.so.0.6600.0)
==106763== by 0x4A95117: ??? (in /usr/lib/libgobject-2.0.so.0.6600.0)
==106763== by 0x4A9583F: g_type_register_fundamental (in /usr/lib/libgobject-2.0.so.0.6600.0)
==106763== by 0x4A7287C: ??? (in /usr/lib/libgobject-2.0.so.0.6600.0)
==106763== by 0x40112DD: call_init.part.0 (in /usr/lib/ld-2.32.so)
==106763== by 0x40113C7: _dl_init (in /usr/lib/ld-2.32.so)
==106763== by 0x40020C9: ??? (in /usr/lib/ld-2.32.so)
==106763==
==106763== 16 bytes in 1 blocks are possibly lost in loss record 94 of 232
==106763== at 0x483A6AF: malloc (vg_replace_malloc.c:306)
==106763== by 0x4B0CA68: g_realloc (in /usr/lib/libglib-2.0.so.0.6600.0)
==106763== by 0x4A9509D: ??? (in /usr/lib/libgobject-2.0.so.0.6600.0)
==106763== by 0x4A9583F: g_type_register_fundamental (in /usr/lib/libgobject-2.0.so.0.6600.0)
==106763== by 0x4A7287C: ??? (in /usr/lib/libgobject-2.0.so.0.6600.0)
==106763== by 0x40112DD: call_init.part.0 (in /usr/lib/ld-2.32.so)
==106763== by 0x40113C7: _dl_init (in /usr/lib/ld-2.32.so)
==106763== by 0x40020C9: ??? (in /usr/lib/ld-2.32.so)
==106763==
==106763== 16 bytes in 1 blocks are possibly lost in loss record 95 of 232
==106763== at 0x483CB65: calloc (vg_replace_malloc.c:760)
==106763== by 0x4B0B941: g_malloc0 (in /usr/lib/libglib-2.0.so.0.6600.0)
==106763== by 0x4A95117: ??? (in /usr/lib/libgobject-2.0.so.0.6600.0)
==106763== by 0x4A9583F: g_type_register_fundamental (in /usr/lib/libgobject-2.0.so.0.6600.0)
==106763== by 0x4A73910: ??? (in /usr/lib/libgobject-2.0.so.0.6600.0)
==106763== by 0x40112DD: call_init.part.0 (in /usr/lib/ld-2.32.so)
==106763== by 0x40113C7: _dl_init (in /usr/lib/ld-2.32.so)
==106763== by 0x40020C9: ??? (in /usr/lib/ld-2.32.so)
==106763==
==106763== 16 bytes in 1 blocks are possibly lost in loss record 96 of 232
==106763== at 0x483A6AF: malloc (vg_replace_malloc.c:306)
==106763== by 0x4B0CA68: g_realloc (in /usr/lib/libglib-2.0.so.0.6600.0)
==106763== by 0x4A9509D: ??? (in /usr/lib/libgobject-2.0.so.0.6600.0)
==106763== by 0x4A9583F: g_type_register_fundamental (in /usr/lib/libgobject-2.0.so.0.6600.0)
==106763== by 0x4A73910: ??? (in /usr/lib/libgobject-2.0.so.0.6600.0)
==106763== by 0x40112DD: call_init.part.0 (in /usr/lib/ld-2.32.so)
==106763== by 0x40113C7: _dl_init (in /usr/lib/ld-2.32.so)
==106763== by 0x40020C9: ??? (in /usr/lib/ld-2.32.so)
==106763==
==106763== 96 bytes in 1 blocks are possibly lost in loss record 212 of 232
==106763== at 0x483CB65: calloc (vg_replace_malloc.c:760)
==106763== by 0x4B0B941: g_malloc0 (in /usr/lib/libglib-2.0.so.0.6600.0)
==106763== by 0x4A89208: ??? (in /usr/lib/libgobject-2.0.so.0.6600.0)
==106763== by 0x4A8A04E: ??? (in /usr/lib/libgobject-2.0.so.0.6600.0)
==106763== by 0x4A72005: ??? (in /usr/lib/libgobject-2.0.so.0.6600.0)
==106763== by 0x40112DD: call_init.part.0 (in /usr/lib/ld-2.32.so)
==106763== by 0x40113C7: _dl_init (in /usr/lib/ld-2.32.so)
==106763== by 0x40020C9: ??? (in /usr/lib/ld-2.32.so)
==106763==
==106763== 96 bytes in 1 blocks are possibly lost in loss record 213 of 232
==106763== at 0x483CB65: calloc (vg_replace_malloc.c:760)
==106763== by 0x4B0B941: g_malloc0 (in /usr/lib/libglib-2.0.so.0.6600.0)
==106763== by 0x4A89208: ??? (in /usr/lib/libgobject-2.0.so.0.6600.0)
==106763== by 0x4A8A04E: ??? (in /usr/lib/libgobject-2.0.so.0.6600.0)
==106763== by 0x4A95831: g_type_register_fundamental (in /usr/lib/libgobject-2.0.so.0.6600.0)
==106763== by 0x4A72755: ??? (in /usr/lib/libgobject-2.0.so.0.6600.0)
==106763== by 0x40112DD: call_init.part.0 (in /usr/lib/ld-2.32.so)
==106763== by 0x40113C7: _dl_init (in /usr/lib/ld-2.32.so)
==106763== by 0x40020C9: ??? (in /usr/lib/ld-2.32.so)
==106763==
==106763== 96 bytes in 1 blocks are possibly lost in loss record 214 of 232
==106763== at 0x483CB65: calloc (vg_replace_malloc.c:760)
==106763== by 0x4B0B941: g_malloc0 (in /usr/lib/libglib-2.0.so.0.6600.0)
==106763== by 0x4A89208: ??? (in /usr/lib/libgobject-2.0.so.0.6600.0)
==106763== by 0x4A8A04E: ??? (in /usr/lib/libgobject-2.0.so.0.6600.0)
==106763== by 0x4A95831: g_type_register_fundamental (in /usr/lib/libgobject-2.0.so.0.6600.0)
==106763== by 0x4A727B4: ??? (in /usr/lib/libgobject-2.0.so.0.6600.0)
==106763== by 0x40112DD: call_init.part.0 (in /usr/lib/ld-2.32.so)
==106763== by 0x40113C7: _dl_init (in /usr/lib/ld-2.32.so)
==106763== by 0x40020C9: ??? (in /usr/lib/ld-2.32.so)
==106763==
==106763== 96 bytes in 1 blocks are possibly lost in loss record 215 of 232
==106763== at 0x483CB65: calloc (vg_replace_malloc.c:760)
==106763== by 0x4B0B941: g_malloc0 (in /usr/lib/libglib-2.0.so.0.6600.0)
==106763== by 0x4A89208: ??? (in /usr/lib/libgobject-2.0.so.0.6600.0)
==106763== by 0x4A8A04E: ??? (in /usr/lib/libgobject-2.0.so.0.6600.0)
==106763== by 0x4A95831: g_type_register_fundamental (in /usr/lib/libgobject-2.0.so.0.6600.0)
==106763== by 0x4A7287C: ??? (in /usr/lib/libgobject-2.0.so.0.6600.0)
==106763== by 0x40112DD: call_init.part.0 (in /usr/lib/ld-2.32.so)
==106763== by 0x40113C7: _dl_init (in /usr/lib/ld-2.32.so)
==106763== by 0x40020C9: ??? (in /usr/lib/ld-2.32.so)
==106763==
==106763== 96 bytes in 1 blocks are possibly lost in loss record 216 of 232
==106763== at 0x483CB65: calloc (vg_replace_malloc.c:760)
==106763== by 0x4B0B941: g_malloc0 (in /usr/lib/libglib-2.0.so.0.6600.0)
==106763== by 0x4A89208: ??? (in /usr/lib/libgobject-2.0.so.0.6600.0)
==106763== by 0x4A8A04E: ??? (in /usr/lib/libgobject-2.0.so.0.6600.0)
==106763== by 0x4A95831: g_type_register_fundamental (in /usr/lib/libgobject-2.0.so.0.6600.0)
==106763== by 0x4A73910: ??? (in /usr/lib/libgobject-2.0.so.0.6600.0)
==106763== by 0x40112DD: call_init.part.0 (in /usr/lib/ld-2.32.so)
==106763== by 0x40113C7: _dl_init (in /usr/lib/ld-2.32.so)
==106763== by 0x40020C9: ??? (in /usr/lib/ld-2.32.so)
==106763==
==106763== 132 bytes in 1 blocks are possibly lost in loss record 218 of 232
==106763== at 0x483CB65: calloc (vg_replace_malloc.c:760)
==106763== by 0x4B0B941: g_malloc0 (in /usr/lib/libglib-2.0.so.0.6600.0)
==106763== by 0x4A8AFCD: ??? (in /usr/lib/libgobject-2.0.so.0.6600.0)
==106763== by 0x4A958B9: g_type_register_fundamental (in /usr/lib/libgobject-2.0.so.0.6600.0)
==106763== by 0x4A72755: ??? (in /usr/lib/libgobject-2.0.so.0.6600.0)
==106763== by 0x40112DD: call_init.part.0 (in /usr/lib/ld-2.32.so)
==106763== by 0x40113C7: _dl_init (in /usr/lib/ld-2.32.so)
==106763== by 0x40020C9: ??? (in /usr/lib/ld-2.32.so)
==106763==
==106763== 132 bytes in 1 blocks are possibly lost in loss record 219 of 232
==106763== at 0x483CB65: calloc (vg_replace_malloc.c:760)
==106763== by 0x4B0B941: g_malloc0 (in /usr/lib/libglib-2.0.so.0.6600.0)
==106763== by 0x4A8AFCD: ??? (in /usr/lib/libgobject-2.0.so.0.6600.0)
==106763== by 0x4A958B9: g_type_register_fundamental (in /usr/lib/libgobject-2.0.so.0.6600.0)
==106763== by 0x4A727B4: ??? (in /usr/lib/libgobject-2.0.so.0.6600.0)
==106763== by 0x40112DD: call_init.part.0 (in /usr/lib/ld-2.32.so)
==106763== by 0x40113C7: _dl_init (in /usr/lib/ld-2.32.so)
==106763== by 0x40020C9: ??? (in /usr/lib/ld-2.32.so)
==106763==
==106763== 148 bytes in 1 blocks are possibly lost in loss record 220 of 232
==106763== at 0x483CB65: calloc (vg_replace_malloc.c:760)
==106763== by 0x4B0B941: g_malloc0 (in /usr/lib/libglib-2.0.so.0.6600.0)
==106763== by 0x4A8ADCD: ??? (in /usr/lib/libgobject-2.0.so.0.6600.0)
==106763== by 0x4A958B9: g_type_register_fundamental (in /usr/lib/libgobject-2.0.so.0.6600.0)
==106763== by 0x4A7287C: ??? (in /usr/lib/libgobject-2.0.so.0.6600.0)
==106763== by 0x40112DD: call_init.part.0 (in /usr/lib/ld-2.32.so)
==106763== by 0x40113C7: _dl_init (in /usr/lib/ld-2.32.so)
==106763== by 0x40020C9: ??? (in /usr/lib/ld-2.32.so)
==106763==
==106763== 148 bytes in 1 blocks are possibly lost in loss record 221 of 232
==106763== at 0x483CB65: calloc (vg_replace_malloc.c:760)
==106763== by 0x4B0B941: g_malloc0 (in /usr/lib/libglib-2.0.so.0.6600.0)
==106763== by 0x4A8ADCD: ??? (in /usr/lib/libgobject-2.0.so.0.6600.0)
==106763== by 0x4A958B9: g_type_register_fundamental (in /usr/lib/libgobject-2.0.so.0.6600.0)
==106763== by 0x4A73910: ??? (in /usr/lib/libgobject-2.0.so.0.6600.0)
==106763== by 0x40112DD: call_init.part.0 (in /usr/lib/ld-2.32.so)
==106763== by 0x40113C7: _dl_init (in /usr/lib/ld-2.32.so)
==106763== by 0x40020C9: ??? (in /usr/lib/ld-2.32.so)
==106763==
==106763== 184 bytes in 1 blocks are possibly lost in loss record 223 of 232
==106763== at 0x483CD7B: realloc (vg_replace_malloc.c:834)
==106763== by 0x4B0CA68: g_realloc (in /usr/lib/libglib-2.0.so.0.6600.0)
==106763== by 0x4A8917F: ??? (in /usr/lib/libgobject-2.0.so.0.6600.0)
==106763== by 0x4A9A6DC: g_type_register_static (in /usr/lib/libgobject-2.0.so.0.6600.0)
==106763== by 0x4A87B02: g_param_type_register_static (in /usr/lib/libgobject-2.0.so.0.6600.0)
==106763== by 0x4A71E67: ??? (in /usr/lib/libgobject-2.0.so.0.6600.0)
==106763== by 0x4A7296C: ??? (in /usr/lib/libgobject-2.0.so.0.6600.0)
==106763== by 0x40112DD: call_init.part.0 (in /usr/lib/ld-2.32.so)
==106763== by 0x40113C7: _dl_init (in /usr/lib/ld-2.32.so)
==106763== by 0x40020C9: ??? (in /usr/lib/ld-2.32.so)
==106763==
==106763== LEAK SUMMARY:
==106763== definitely lost: 0 bytes in 0 blocks
==106763== indirectly lost: 0 bytes in 0 blocks
==106763== possibly lost: 1,352 bytes in 18 blocks
==106763== still reachable: 35,508 bytes in 214 blocks
==106763== of which reachable via heuristic:
==106763== newarray : 1,536 bytes in 16 blocks
==106763== suppressed: 0 bytes in 0 blocks
==106763== Reachable blocks (those to which a pointer was found) are not shown.
==106763== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==106763==
==106763== For lists of detected and suppressed errors, rerun with: -s
==106763== ERROR SUMMARY: 18 errors from 18 contexts (suppressed: 0 from 0)
As you can see, the leaks don't come from the real use of libnotify
rather than from just linking it.
Therefore I tried the following code:
/* #include <libnotify/notify.h> */
#include <stdlib.h>
int main() {
/* notify_init ("Hello world!"); */
/* NotifyNotification * Hello = notify_notification_new ("Hello world", "This is an example notification.", "dialog-information"); */
/* notify_notification_show (Hello, NULL); */
/* g_object_unref(G_OBJECT(Hello)); */
/* notify_uninit(); */
return 0;
}
compiled as cc -g -o mwe mwe.c
and
executed as valgrind --tool=memcheck --leak-check=full ./mwe
prints
$ valgrind --tool=memcheck --leak-check=full ./mwe
==109214== Memcheck, a memory error detector
==109214== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==109214== Using Valgrind-3.16.1 and LibVEX; rerun with -h for copyright info
==109214== Command: ./mwe
==109214==
==109214==
==109214== HEAP SUMMARY:
==109214== in use at exit: 0 bytes in 0 blocks
==109214== total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==109214==
==109214== All heap blocks were freed -- no leaks are possible
==109214==
==109214== For lists of detected and suppressed errors, rerun with: -s
==109214== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
This lead me to the conclusion, that the memory leak has to come from libnotify
and is caused by just linking the lib to a project (when I link and use the library I get the memory leaks as well).