I have came around something strange with valgrind lately. If I write for instance a simple test.c file:
#include <stdio.h>
#include <stdlib.h>
int main(){
printf("hello\n");
}
and compile it with this command: gcc $(pkg-config --cflags --libs gtk+-3.0) -g3 -O0 and then check for memory leaks with: valgrind --leak-check=full ./a.out I get something like:
==7588== Memcheck, a memory error detector
==7588== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==7588== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==7588== Command: ./a.out
==7588==
hello
==7588==
==7588== HEAP SUMMARY:
==7588== in use at exit: 51,837 bytes in 245 blocks
==7588== total heap usage: 1,551 allocs, 1,306 frees, 394,322,404 bytes allocated
==7588==
==7588== 16 bytes in 1 blocks are possibly lost in loss record 89 of 244
==7588== at 0x4C2A987: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7588== by 0x6DE35B1: g_malloc0 (in /usr/lib/libglib-2.0.so.0.4400.1)
==7588== by 0x6B70294: ??? (in /usr/lib/libgobject-2.0.so.0.4400.1)
==7588== by 0x6B73F92: g_type_register_fundamental (in /usr/lib/libgobject-2.0.so.0.4400.1)
==7588== by 0x6B5464B: ??? (in /usr/lib/libgobject-2.0.so.0.4400.1)
==7588== by 0x6B4E67D: ??? (in /usr/lib/libgobject-2.0.so.0.4400.1)
==7588== by 0x400F279: call_init.part.0 (in /usr/lib/ld-2.22.so)
==7588== by 0x400F38A: _dl_init (in /usr/lib/ld-2.22.so)
==7588== by 0x4000DB9: ??? (in /usr/lib/ld-2.22.so)
==7588==
==7588== 16 bytes in 1 blocks are possibly lost in loss record 90 of 244
==7588== at 0x4C28C10: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7588== by 0x4C2AADE: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7588== by 0x6DE361D: g_realloc (in /usr/lib/libglib-2.0.so.0.4400.1)
==7588== by 0x6B70148: ??? (in /usr/lib/libgobject-2.0.so.0.4400.1)
==7588== by 0x6B73F92: g_type_register_fundamental (in /usr/lib/libgobject-2.0.so.0.4400.1)
==7588== by 0x6B5464B: ??? (in /usr/lib/libgobject-2.0.so.0.4400.1)
==7588== by 0x6B4E67D: ??? (in /usr/lib/libgobject-2.0.so.0.4400.1)
==7588== by 0x400F279: call_init.part.0 (in /usr/lib/ld-2.22.so)
==7588== by 0x400F38A: _dl_init (in /usr/lib/ld-2.22.so)
==7588== by 0x4000DB9: ??? (in /usr/lib/ld-2.22.so)
==7588==
.
.
.
==7588==
==7588== LEAK SUMMARY:
==7588== definitely lost: 0 bytes in 0 blocks
==7588== indirectly lost: 0 bytes in 0 blocks
==7588== possibly lost: 1,352 bytes in 18 blocks
==7588== still reachable: 50,485 bytes in 227 blocks
==7588== of which reachable via heuristic:
==7588== newarray : 1,536 bytes in 16 blocks
==7588== suppressed: 0 bytes in 0 blocks
==7588== Reachable blocks (those to which a pointer was found) are not shown.
==7588== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==7588==
==7588== For counts of detected and suppressed errors, rerun with: -v
==7588== ERROR SUMMARY: 18 errors from 18 contexts (suppressed: 0 from 0)
Whereas if I compile it normally, with: gcc -g3 -O0 test.c and then check for memory leaks with: valgrind --leak-check=full ./a.out, I obviously don't get any memory leaks:
==7734== Memcheck, a memory error detector
==7734== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==7734== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==7734== Command: ./a.out
==7734==
hello
==7734==
==7734== HEAP SUMMARY:
==7734== in use at exit: 0 bytes in 0 blocks
==7734== total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==7734==
==7734== All heap blocks were freed -- no leaks are possible
==7734==
==7734== For counts of detected and suppressed errors, rerun with: -v
==7734== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
So my question is: why does linking gtk generate so many memory leaks ?
Thank you very much in advance
Related
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.
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.
This question already has answers here:
Valgrind showing memory leak for printf and unused blocks
(2 answers)
Valgrind reports errors for a very simple C program
(3 answers)
Closed 6 years ago.
This simple program
///test.c
#include <stdio.h>
int main(){
double d = 13.37;
char buf[128];
snprintf(buf, 128, "%f", d);
return 0;
}
is leaking memory according to valgrind, the valgrind output when run
with --leak-check=full is
==29114== Memcheck, a memory error detector
==29114== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==29114== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==29114== Command: ./test
==29114==
==29114==
==29114== HEAP SUMMARY:
==29114== in use at exit: 22,175 bytes in 187 blocks
==29114== total heap usage: 263 allocs, 76 frees, 28,271 bytes allocated
==29114==
==29114== 148 (80 direct, 68 indirect) bytes in 1 blocks are definitely lost in loss record 43 of 66
==29114== at 0x100008EBB: malloc (in /usr/local/Cellar/valgrind/3.11.0/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==29114== by 0x1001C34A2: __Balloc_D2A (in /usr/lib/system/libsystem_c.dylib)
==29114== by 0x1001C3DEB: __d2b_D2A (in /usr/lib/system/libsystem_c.dylib)
==29114== by 0x1001C0443: __dtoa (in /usr/lib/system/libsystem_c.dylib)
==29114== by 0x1001E907A: __vfprintf (in /usr/lib/system/libsystem_c.dylib)
==29114== by 0x10021235C: __v2printf (in /usr/lib/system/libsystem_c.dylib)
==29114== by 0x1001F65A8: _vsnprintf (in /usr/lib/system/libsystem_c.dylib)
==29114== by 0x1001F665D: vsnprintf (in /usr/lib/system/libsystem_c.dylib)
==29114== by 0x100227CBF: __snprintf_chk (in /usr/lib/system/libsystem_c.dylib)
==29114== by 0x100000F4B: main (in ./test)
==29114==
==29114== LEAK SUMMARY:
==29114== definitely lost: 80 bytes in 1 blocks
==29114== indirectly lost: 68 bytes in 2 blocks
==29114== possibly lost: 0 bytes in 0 blocks
==29114== still reachable: 0 bytes in 0 blocks
==29114== suppressed: 22,027 bytes in 184 blocks
==29114==
==29114== For counts of detected and suppressed errors, rerun with: -v
==29114== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 18 from 18)
Either I'm misunderstanding something or snprintf seems to be leaking.
I'm on os x if it matters.
Edit: im interested in the "definitely lost" and "indirectly lost" memory leak not the suppressed memory (which isn't a leak).
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.
Consider this code:
int main(int argc, char const *argv[])
{
char *string = NULL;
string = malloc(sizeof(char) * 30);
free(string);
return 0;
}
I malloc a char pointer then I free it after. Now consider the valgrind output:
==58317== Memcheck, a memory error detector
==58317== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==58317== Using Valgrind-3.11.0.SVN and LibVEX; rerun with -h for copyright info
==58317== Command: ./a.out
==58317==
==58317==
==58317== HEAP SUMMARY:
==58317== in use at exit: 34,941 bytes in 424 blocks
==58317== total heap usage: 505 allocs, 81 frees, 41,099 bytes allocated
==58317==
==58317== LEAK SUMMARY:
==58317== definitely lost: 0 bytes in 0 blocks
==58317== indirectly lost: 0 bytes in 0 blocks
==58317== possibly lost: 0 bytes in 0 blocks
==58317== still reachable: 0 bytes in 0 blocks
==58317== suppressed: 34,941 bytes in 424 blocks
==58317==
==58317== For counts of detected and suppressed errors, rerun with: -v
==58317== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
How is it possible to have that many mallocs and frees?
Edit: This is what I get when I run with valgrind --leak-check=yes --gen-suppressions=all ./a.out, I am trying to make a supp file.
==60943== Memcheck, a memory error detector
==60943== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==60943== Using Valgrind-3.11.0.SVN and LibVEX; rerun with -h for copyright info
==60943== Command: ./a.out
==60943==
==60943==
==60943== HEAP SUMMARY:
==60943== in use at exit: 34,941 bytes in 424 blocks
==60943== total heap usage: 505 allocs, 81 frees, 41,099 bytes allocated
==60943==
==60943== LEAK SUMMARY:
==60943== definitely lost: 0 bytes in 0 blocks
==60943== indirectly lost: 0 bytes in 0 blocks
==60943== possibly lost: 0 bytes in 0 blocks
==60943== still reachable: 0 bytes in 0 blocks
==60943== suppressed: 34,941 bytes in 424 blocks
==60943==
==60943== For counts of detected and suppressed errors, rerun with: -v
==60943== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 15 from 15)
Those blocks were allocated (and some of them freed as well) by a system library that was linked into your executable.
Valgrind has a default suppression file that suppresses leaks in system libraries, which is what you can see further in the output :
==58317== suppressed: 34,941 bytes in 424 blocks
If you want more details on what exactly was suppressed, you can use the -v option.