How to fix Gqueue memory leaks? - c

I've been testing this small code trying to learn how to use glib, and i came up with this memory leaks when using Gqueue . this is the code
#include <stdio.h>
#include <glib.h>
int main (){
GQueue *test = NULL;
test = g_queue_new();
g_queue_push_tail(test,"hola mundo");
printf("%s \n",(char *)g_queue_peek_head(test));
g_queue_free(test);
return 0;
}
And this is wath valgrind shows
==36160== Memcheck, a memory error detector
==36160== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==36160== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==36160== Command: ./testgqueue
==36160==
hola mundo
==36160==
==36160== HEAP SUMMARY:
==36160== in use at exit: 18,636 bytes in 7 blocks
==36160== total heap usage: 9 allocs, 2 frees, 19,684 bytes allocated
==36160==
==36160== 24 bytes in 1 blocks are definitely lost in loss record 2 of 7
==36160== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==36160== by 0x48B7E98: g_malloc (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.6)
==36160== by 0x48D0485: g_slice_alloc (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.6)
==36160== by 0x48D0AAD: g_slice_alloc0 (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6400.6)
==36160== by 0x1091E1: main (in /home/adolfo/Documents/cosas/testGlib/testgqueue)
==36160==
==36160== LEAK SUMMARY:
==36160== definitely lost: 24 bytes in 1 blocks
==36160== indirectly lost: 0 bytes in 0 blocks
==36160== possibly lost: 0 bytes in 0 blocks
==36160== still reachable: 18,612 bytes in 6 blocks
==36160== suppressed: 0 bytes in 0 blocks
==36160== Reachable blocks (those to which a pointer was found) are not shown.
==36160== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==36160==
==36160== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

g_queue_clear() frees the memory of the queue elements, but not the queue itself. You need
g_queue_free(test);
after that.

Related

Free all memory allocated by LLVM on exit

I am using LLVM-C to program a little toy language.
I am using also valgrind to check for memory leaks.
Here is my basic baby program:
#include <stdio.h>
#include <llvm-c/Core.h>
int main()
{
size_t length;
LLVMModuleRef module = LLVMModuleCreateWithName("llvm.hello");
printf("Module name: %s\n", LLVMGetModuleIdentifier(module, &length));
LLVMDisposeModule(module);
LLVMShutDown();
return 0;
}
I can compile and run the program normally, as expected. However when I run the program through valgrind, it tells me I have some "still reachable" allocated memory like this.
valgrind --leak-check=full out/hello_llvm
==5807== LEAK SUMMARY:
==5807== definitely lost: 0 bytes in 0 blocks
==5807== indirectly lost: 0 bytes in 0 blocks
==5807== possibly lost: 0 bytes in 0 blocks
==5807== still reachable: 56 bytes in 2 blocks
==5807== suppressed: 0 bytes in 0 blocks
While searching over here on this site for an answer, I found many coders are saying that "still reachable" memory leaks are not such a big deal. I don't want to argue about that. What I want is to get rid of ALL allocated memory before terminating my program.
Is there any way I can reduce that allocated memory down to zero before termination?
It also makes me very nervous when valgrind does not give 0, in those cases I create a suppression file, if you want to give it a try:
Create and compile a minimal test:
> cat demo.c
#include <stdlib.h>
int main(void)
{
malloc(10); // leak
}
Create a supression file:
valgrind --leak-check=full --show-reachable=yes --error-limit=no --gen-suppressions=all --log-file=minimal.supp ./demo
Edit the generated minimal.supp file, you will see something like
==3102== Memcheck, a memory error detector
==3102== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==3102== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==3102== Command: ./demo
==3102== Parent PID: 2633
==3102==
==3102==
==3102== HEAP SUMMARY:
==3102== in use at exit: 10 bytes in 1 blocks
==3102== total heap usage: 1 allocs, 0 frees, 10 bytes allocated
==3102==
==3102== 10 bytes in 1 blocks are definitely lost in loss record 1 of 1
==3102== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==3102== by 0x10915A: main (in /home/david/demo)
==3102==
{
<insert_a_suppression_name_here>
Memcheck:Leak
match-leak-kinds: definite
fun:malloc
fun:main
}
==3102== LEAK SUMMARY:
==3102== definitely lost: 10 bytes in 1 blocks
==3102== indirectly lost: 0 bytes in 0 blocks
==3102== possibly lost: 0 bytes in 0 blocks
==3102== still reachable: 0 bytes in 0 blocks
==3102== suppressed: 0 bytes in 0 blocks
==3102==
==3102== For lists of detected and suppressed errors, rerun with: -s
==3102== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Remove all the lines starting with == and save something like:
{
<my stupid external LLVM leak>
Memcheck:Leak
match-leak-kinds: definite
fun:malloc
fun:main
}
Now run valgrind with the supression file:
valgrind --tool=memcheck --leak-check=full --show-reachable=yes --error-limit=no --suppressions=minimal.supp ./demo
The result is:
==3348== Memcheck, a memory error detector
==3348== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==3348== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==3348== Command: ./demo
==3348==
==3348==
==3348== HEAP SUMMARY:
==3348== in use at exit: 10 bytes in 1 blocks
==3348== total heap usage: 1 allocs, 0 frees, 10 bytes allocated
==3348==
==3348== LEAK SUMMARY:
==3348== definitely lost: 0 bytes in 0 blocks
==3348== indirectly lost: 0 bytes in 0 blocks
==3348== possibly lost: 0 bytes in 0 blocks
==3348== still reachable: 0 bytes in 0 blocks
==3348== suppressed: 10 bytes in 1 blocks
==3348==
==3348== For lists of detected and suppressed errors, rerun with: -s
==3348== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 1 from 1)
As you can see, the leak is moved from "definitely lost" to "suppressed"

Memory leak in simple Hello World C program

I'm a beginner in C, and I'm wondering why this simple Hello World program has a memory leak:
#include <stdio.h>
int main(int argc, const char *argv[]) {
printf("Hello world\n");
return 0;
}
It compiles, but this is what Valgrind reports:
> valgrind ./a.out
==36468== Memcheck, a memory error detector
==36468== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==36468== Using Valgrind-3.12.0.SVN and LibVEX; rerun with -h for copyright info
==36468== Command: ./a.out
==36468==
Hello world
==36468==
==36468== HEAP SUMMARY:
==36468== in use at exit: 26,207 bytes in 190 blocks
==36468== total heap usage: 264 allocs, 74 frees, 32,175 bytes allocated
==36468==
==36468== LEAK SUMMARY:
==36468== definitely lost: 0 bytes in 0 blocks
==36468== indirectly lost: 0 bytes in 0 blocks
==36468== possibly lost: 2,064 bytes in 1 blocks
==36468== still reachable: 0 bytes in 0 blocks
==36468== suppressed: 24,143 bytes in 189 blocks
==36468== Rerun with --leak-check=full to see details of leaked memory
==36468==
==36468== For counts of detected and suppressed errors, rerun with: -v
==36468== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
What's with the "possibly lost: 2,064 bytes in 1 blocks" and "suppressed: 24,143 bytes in 189 blocks"? I never used malloc so I'm not sure why this is happening.

Valgrind definitely lost and reachable with exit vs main return

Valgrind reports definitely lost memory if I exit main with return 0;, but reports still reachable memory if I exit main with exit(0);.
test-reachable.c:
#include <stdlib.h>
int main() {
void *data = malloc(256);
exit(0);
}
test-lost.c:
#include <stdlib.h>
int main() {
void *data = malloc(256);
return 0;
}
Behavior:
$ gcc test-reachable.c -o test-reachable
$ valgrind --leak-check=yes ./test-reachable
==7696== Memcheck, a memory error detector
==7696== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==7696== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==7696== Command: ./test-reachable
==7696==
==7696==
==7696== HEAP SUMMARY:
==7696== in use at exit: 256 bytes in 1 blocks
==7696== total heap usage: 1 allocs, 0 frees, 256 bytes allocated
==7696==
==7696== LEAK SUMMARY:
==7696== definitely lost: 0 bytes in 0 blocks
==7696== indirectly lost: 0 bytes in 0 blocks
==7696== possibly lost: 0 bytes in 0 blocks
==7696== still reachable: 256 bytes in 1 blocks
==7696== suppressed: 0 bytes in 0 blocks
==7696== Reachable blocks (those to which a pointer was found) are not shown.
==7696== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==7696==
==7696== For counts of detected and suppressed errors, rerun with: -v
==7696== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
$ gcc test-lost.c -o test-lost
$ valgrind --leak-check=yes ./test-lost
==7774== Memcheck, a memory error detector
==7774== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==7774== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==7774== Command: ./test-lost
==7774==
==7774==
==7774== HEAP SUMMARY:
==7774== in use at exit: 256 bytes in 1 blocks
==7774== total heap usage: 1 allocs, 0 frees, 256 bytes allocated
==7774==
==7774== 256 bytes in 1 blocks are definitely lost in loss record 1 of 1
==7774== at 0x4C2C080: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7774== by 0x40051C: main (in /tmp/test-lost)
==7774==
==7774== LEAK SUMMARY:
==7774== definitely lost: 256 bytes in 1 blocks
==7774== indirectly lost: 0 bytes in 0 blocks
==7774== possibly lost: 0 bytes in 0 blocks
==7774== still reachable: 0 bytes in 0 blocks
==7774== suppressed: 0 bytes in 0 blocks
==7774==
==7774== For counts of detected and suppressed errors, rerun with: -v
==7774== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Shouldn't these behave the same?
Shouldn't these behave the same?
No.
In test-reachable.c the memory is referenced by the stack variable data at the time of the exit of the program, so it is still reachable, while in test-lost.c the memory is not referenced anymore because the main function has already returned, the reference does not exist anymore, the memory is definitely lost.
In C++ when return in main() is called then the destructors will be called for locally scoped objects whereas if exit() is called then no destructor will be called for locally scoped objects.
I think this is similar in C with regards to objects allocated on the stack.
That probably explains why in the return case non freed memory is treated as definitely lost and in the exit(0) case the memory is reported as still reachable.

Why valgrind report my memory as "definitely lost"?

Consider this code:
#include <stdlib.h>
int* alloc()
{
return malloc(250 * sizeof(int));
}
int main()
{
int i;
int *vars[3];
for(i = 0; i < 3; ++i) {
vars[i] = alloc();
}
}
Valgrind output:
$ valgrind --leak-check=full ./lala
==16775== Memcheck, a memory error detector
==16775== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==16775== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==16775== Command: ./lala
==16775==
==16775==
==16775== HEAP SUMMARY:
==16775== in use at exit: 3,000 bytes in 3 blocks
==16775== total heap usage: 3 allocs, 0 frees, 3,000 bytes allocated
==16775==
==16775== 3,000 bytes in 3 blocks are definitely lost in loss record 1 of 1
==16775== at 0x4C2BBA0: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==16775== by 0x4005B3: alloc (lala.c:5)
==16775== by 0x4005DF: main (lala.c:13)
==16775==
==16775== LEAK SUMMARY:
==16775== definitely lost: 3,000 bytes in 3 blocks
==16775== indirectly lost: 0 bytes in 0 blocks
==16775== possibly lost: 0 bytes in 0 blocks
==16775== still reachable: 0 bytes in 0 blocks
==16775== suppressed: 0 bytes in 0 blocks
==16775==
==16775== For counts of detected and suppressed errors, rerun with: -v
==16775== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
According to Valgrind's manual:
If --leak-check is set appropriately, for each remaining block,
Memcheck determines if the block is reachable from pointers within the
root-set. The root-set consists of (a) general purpose registers of
all threads, and (b) initialized, aligned, pointer-sized data words in
accessible client memory, including stacks.
For what I understand, since the "definitely lost" memory are still pointed to from the main() function's stack, they should be categorized as "still reachable", right?
If not, how can I configure Valgrind to try to reach memory blocks from main's stack, to determine if they are "still reachable"?
EDIT:
Please don't tell me to free the pointers at the end of main, that is not what I am asking about. For the distinction between "still reachable" and "definitely lost" on Valgrind terms, see this answer: https://stackoverflow.com/a/3857638/578749
Your memory is definitely lost when the stack of main is destroyed, that is, when it returns. Thus, the solution is not to return.
#include <stdlib.h>
int main()
{
/* your code here */
exit(0);
}
The behavior or main returning 0 or exit(0) should be equivalent.
Now the output is:
==5035== Memcheck, a memory error detector
==5035== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==5035== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==5035== Command: ./a.out
==5035==
==5035==
==5035== HEAP SUMMARY:
==5035== in use at exit: 3,000 bytes in 3 blocks
==5035== total heap usage: 3 allocs, 0 frees, 3,000 bytes allocated
==5035==
==5035== LEAK SUMMARY:
==5035== definitely lost: 0 bytes in 0 blocks
==5035== indirectly lost: 0 bytes in 0 blocks
==5035== possibly lost: 0 bytes in 0 blocks
==5035== still reachable: 3,000 bytes in 3 blocks
==5035== suppressed: 0 bytes in 0 blocks
==5035== Reachable blocks (those to which a pointer was found) are not shown.
==5035== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==5035==
==5035== For counts of detected and suppressed errors, rerun with: -v
==5035== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

Does glib2 actually leak memory with ALWAYS-MALLOC?

This question is not a duplicate of many others, bekause I do use G_DEBUG=gc-friendly and G_SLICE=always-malloc
Here is the source code:
#include <glib.h>
int main (int argc, char *argv[])
{
GHashTable *ht;
ht=g_hash_table_new(g_str_hash,g_str_equal);
g_hash_table_insert(ht,"foo","bar");
g_hash_table_destroy(ht);
return 0;
}
And here is Valgrind's output on this code:
# G_DEBUG=gc-friendly G_SLICE=always-malloc valgrind --leak-check=full --show-reachable=yes ./test_vg
==1880== Memcheck, a memory error detector
==1880== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==1880== Using Valgrind-3.6.0 and LibVEX; rerun with -h for copyright info
==1880== Command: ./test_vg
==1880==
==1880==
==1880== HEAP SUMMARY:
==1880== in use at exit: 1,260 bytes in 3 blocks
==1880== total heap usage: 5 allocs, 2 frees, 1,524 bytes allocated
==1880==
==1880== 252 bytes in 1 blocks are still reachable in loss record 1 of 3
==1880== at 0x4A04A28: calloc (vg_replace_malloc.c:467)
==1880== by 0x35C8241707: g_malloc0 (in /lib64/libglib-2.0.so.0.2200.5)
==1880== by 0x35C8255742: ??? (in /lib64/libglib-2.0.so.0.2200.5)
==1880== by 0x35C825669D: g_slice_alloc (in /lib64/libglib-2.0.so.0.2200.5)
==1880== by 0x35C822B1D2: g_hash_table_new_full (in /lib64/libglib-2.0.so.0.2200.5)
==1880== by 0x400671: main (in /home/data/test_vg)
==1880==
==1880== 504 bytes in 1 blocks are still reachable in loss record 2 of 3
==1880== at 0x4A04A28: calloc (vg_replace_malloc.c:467)
==1880== by 0x35C8241707: g_malloc0 (in /lib64/libglib-2.0.so.0.2200.5)
==1880== by 0x35C8255722: ??? (in /lib64/libglib-2.0.so.0.2200.5)
==1880== by 0x35C825669D: g_slice_alloc (in /lib64/libglib-2.0.so.0.2200.5)
==1880== by 0x35C822B1D2: g_hash_table_new_full (in /lib64/libglib-2.0.so.0.2200.5)
==1880== by 0x400671: main (in /home/data/test_vg)
==1880==
==1880== 504 bytes in 1 blocks are still reachable in loss record 3 of 3
==1880== at 0x4A04A28: calloc (vg_replace_malloc.c:467)
==1880== by 0x35C8241707: g_malloc0 (in /lib64/libglib-2.0.so.0.2200.5)
==1880== by 0x35C825578B: ??? (in /lib64/libglib-2.0.so.0.2200.5)
==1880== by 0x35C825669D: g_slice_alloc (in /lib64/libglib-2.0.so.0.2200.5)
==1880== by 0x35C822B1D2: g_hash_table_new_full (in /lib64/libglib-2.0.so.0.2200.5)
==1880== by 0x400671: main (in /home/data/test_vg)
==1880==
==1880== LEAK SUMMARY:
==1880== definitely lost: 0 bytes in 0 blocks
==1880== indirectly lost: 0 bytes in 0 blocks
==1880== possibly lost: 0 bytes in 0 blocks
==1880== still reachable: 1,260 bytes in 3 blocks
==1880== suppressed: 0 bytes in 0 blocks
==1880==
==1880== For counts of detected and suppressed errors, rerun with: -v
==1880== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 6)
Is it a memory-leak?
To answer your question: No, this is not a memory leak in the traditional sense. Your code is fine.
Even if you use G_DEBUG=gc-friendly and G_SLICE=always-malloc, GLib always leaves "still reachable" memory on exit. Don't use the --show-reachable=yes option, otherwise you'll always have a polluted Valgrind output when using GLib. However, be careful if you allocate memory to which you keep pointers in static or global variables ("still reachable" memory). In this case you might end up ignoring your own "real" leaks.
I have always had trouble with a lot of false and unreachable items when using Valgrind to check GLib 2 programs. In your case, the leaks seem to be from the creation of the hash table. I would create a second hash table and see if you get additional blocks (otherwise, it could be some internal initialization in GLib).
Some notes on using Valgrind with GLIB and GTK are at wiki.gnome.org.
Try passing --suppressions=/usr/share/glib-2.0/valgrind/glib.supp to valgrind. It suppresses the false positives from GLib.

Resources