Hello all,
Thanks for the feedback, and I will summarize the "howto" on this. I believe
the same memory leakage reporting issue is being discussed in the thread
"checking for memory leaks in gtk". I am ok with Glib not explicitly freeing
some singletons on exit, but the real issue is to distinguish genuine leaks
in user code from "leaks" that are attributable to Glib.
First, the problem. When the `G_' macros are defined, less memory is
reported as leaked, but some still remains unaccounted for according to
mtrace. See the comparison below:
$ cat test1.c
#include <glib.h>
#include <mcheck.h>
int main()
{
mtrace();
GHashTable* hash_table;
hash_table=g_hash_table_new(g_str_hash, g_str_equal);
g_hash_table_unref (hash_table);
return 1;
}
$ gcc test1.c -o test1 -I/usr/include/glib-2.0/
-I/usr/lib64/glib-2.0/include/ -lglib-2.0
$ export MALLOC_TRACE=0.mtrace.log
$ ./test1; mtrace ./test1 $MALLOC_TRACE
Memory not freed:
-----------------
Address Size Caller
0x0000000000601460 0x1f8 at 0x3fea834002
0x0000000000601660 0xfc at 0x3fea834002
0x0000000000601770 0x1f8 at 0x3fea834002
0x0000000000601970 0x7f0 at 0x3fea834002
0x0000000000602400 0x3f0 at 0x3fea8423e1
0x0000000000602800 0x3f0 at 0x3fea8423e1
Now, when the G_ macros are defined, less memory is reported as leaked.
$ export G_DEBUG=gc-friendly
$ export G_SLICE=always-malloc
$ ./test1; mtrace ./test1 $MALLOC_TRACE
Memory not freed:
-----------------
Address Size Caller
0x0000000000601460 0x1f8 at 0x3fea834002
0x0000000000601660 0xfc at 0x3fea834002
0x0000000000601770 0x1f8 at 0x3fea834002
Simple cases such as:
malloc(20);
GHashTable* hash_table;
hash_table=g_hash_table_new(g_str_hash, g_str_equal);
g_hash_table_unref (hash_table);
can be easily caught by adding the -g option when compiling:
$ gcc -g test1.c -o test1 -I/usr/include/glib-2.0/
-I/usr/lib64/glib-2.0/include/ -lglib-2.0
$ ./test1; mtrace ./test1 $MALLOC_TRACE
Memory not freed:
-----------------
Address Size Caller
0x0000000000601460 0x14 at /home/user/devel/linux/glib/test1.c:13
<-------- obviously, your code does not free allocated memory
0x0000000000601480 0x1f8 at 0x3fea834002
0x0000000000601680 0xfc at 0x3fea834002
0x0000000000601790 0x1f8 at 0x3fea834002
But when leaks are related to not using glib properly, such as not calling
unref, things are more difficult to diagnose:
GHashTable* hash_table;
hash_table=g_hash_table_new(g_str_hash, g_str_equal);
$ gcc -g test1.c -o test1 -I/usr/include/glib-2.0/
-I/usr/lib64/glib-2.0/include/ -lglib-2.0
$ ./test1; mtrace ./test1 $MALLOC_TRACE
Memory not freed:
-----------------
Address Size Caller
0x0000000000601460 0x1f8 at 0x3fea834002
0x0000000000601660 0xfc at 0x3fea834002
0x0000000000601770 0x1f8 at 0x3fea834002
0x0000000000601970 0x38 at 0x3fea83407b
0x00000000006019b0 0x58 at 0x3fea834002 <----------- Is there an memory
allocation error? If yes, where and why?
With valgrind, the diagnostics is much better though (note the
--leak-check=full option for valgrind and the -g option for gcc):
$ G_SLICE=always-malloc G_DEBUG=gc-friendly valgrind --tool=memcheck
--leak-check=full ./test1
--- some lines cut out
==4071== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 4 from 1)
==4071== malloc/free: in use at exit: 2,484 bytes in 7 blocks.
==4071== malloc/free: 7 allocs, 0 frees, 2,484 bytes allocated.
==4071== For counts of detected errors, rerun with: -v
==4071== searching for pointers to 7 not-freed blocks.
==4071== checked 74,704 bytes.
==4071==
==4071== 144 (56 direct, 88 indirect) bytes in 1 blocks are definitely lost
in loss record 1 of 5
==4071== at 0x4A05996: malloc (vg_replace_malloc.c:149)
==4071== by 0x3FEA83407A: g_malloc (in /lib64/libglib-2.0.so.0.1200.13)
==4071== by 0x3FEA820CF2: g_hash_table_new_full (in
/lib64/libglib-2.0.so.0.1200.13)
==4071== by 0x4005E3: main (test1.c:13)
<----------------------------------------------------------- AHA! there's
the culprit
--- some lines cut out
And when the leak is fixed (add an unref call to the code above), the
valgrind output looks better:
==4105== LEAK SUMMARY:
==4105== definitely lost: 0 bytes in 0 blocks.
==4105== possibly lost: 0 bytes in 0 blocks.
==4105== still reachable: 2,340 bytes in 5 blocks.
==4105== suppressed: 0 bytes in 0 blocks.
So I think this pretty much solves my issue of checking for memory leaks
with glib, many thanks for your help.
Regards,
Ovidiu
_______________________________________________
gtk-list mailing list
[email protected]
http://mail.gnome.org/mailman/listinfo/gtk-list