If I run valgrind
valgrind --show-reachable=yes /home/costa/Desktop/zadacha_2_7/main.c
it says that I have Still Reachable, so I understand that it means that there is some memory, which wasn't deallocated.
Here is valgrind's output:
==2841== Memcheck, a memory error detector
==2841== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==2841== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==2841== Command: /home/costa/Desktop/zadacha_2_7/main.c
==2841== /home/costa/Desktop/zadacha_2_7/main.c: 5:
/home/costa/Desktop/zadacha_2_7/main.c: Syntax error: "(" unexpected
==2841==
==2841== HEAP SUMMARY:
==2841== in use at exit: 1,084 bytes in 68 blocks
==2841== total heap usage: 70 allocs, 2 frees, 2,100 bytes allocated
==2841==
==2841== LEAK SUMMARY:
==2841== definitely lost: 0 bytes in 0 blocks
==2841== indirectly lost: 0 bytes in 0 blocks
==2841== possibly lost: 0 bytes in 0 blocks
==2841== still reachable: 1,084 bytes in 68 blocks
==2841== suppressed: 0 bytes in 0 blocks
==2841== Rerun with --leak-check=full to see details of leaked memory
==2841==
==2841== For counts of detected and suppressed errors, rerun with: -v
==2841== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
So, I'd like to see these reachable blocks (that are not shown), how can I do that?
I don't get it, why doesn't valgrind show anything about these blocks with option --show-reachable=yes?
Cf the output of valgrind you copied here:
==2841== Rerun with --leak-check=full to see details of leaked memory
Related
First, I have ran valgrind to make sure that (on the default settings) there are zero errors. Then, I decided to check for leaks with something like: --leak-check=full
I have code that looks something like char* variable=malloc(sizeof(char)*(strlen(in)+1)); and valgrind reports that memory is "definitely lost."
The only other line of code I have access to (this is in a library callback function) is the line of code where in is declared. This is a function argument of type void * (though in this case I'm hoping we can safely assume the value to be null terminated.)
Having
#include <stdlib.h>
char * G;
int main()
{
char * l = malloc(10);
G = malloc(20);
}
The execution under valgrind gives :
pi#raspberrypi:/tmp $ valgrind --leak-check=full ./a.out
==11087== Memcheck, a memory error detector
==11087== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==11087== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==11087== Command: ./a.out
==11087==
==11087==
==11087== HEAP SUMMARY:
==11087== in use at exit: 30 bytes in 2 blocks
==11087== total heap usage: 2 allocs, 0 frees, 30 bytes allocated
==11087==
==11087== 10 bytes in 1 blocks are definitely lost in loss record 1 of 2
==11087== at 0x4847568: malloc (vg_replace_malloc.c:299)
==11087== by 0x10453: main (mm.c:7)
==11087==
==11087== LEAK SUMMARY:
==11087== definitely lost: 10 bytes in 1 blocks
==11087== indirectly lost: 0 bytes in 0 blocks
==11087== possibly lost: 0 bytes in 0 blocks
==11087== still reachable: 20 bytes in 1 blocks
==11087== suppressed: 0 bytes in 0 blocks
==11087== Reachable blocks (those to which a pointer was found) are not shown.
==11087== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==11087==
==11087== For counts of detected and suppressed errors, rerun with: -v
==11087== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 6 from 3)
The malloc(10) is definitely lost because there is no way to access it at the end of the execution (here out of main)
The malloc(20) is not lost because still reachable through G
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:
#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)
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.
When using the dlfcn family like so:
#include <stdio.h>
#include <dlfcn.h>
typedef int(*timefunc_t)(void*);
int main()
{
timefunc_t fun;
void* handle;
handle = dlopen("libc.so.6", RTLD_LAZY);
fun = (timefunc_t)dlsym(handle, "time");
printf("time=%d\n", fun(NULL));
dlclose(handle);
return 0;
}
It causes a Memory leak:
==28803== Memcheck, a memory error detector
==28803== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==28803== Using Valgrind-3.6.1 and LibVEX; rerun with -h for copyright info
==28803== Command: ./dl
==28803==
time=1309249569
==28803==
==28803== HEAP SUMMARY:
==28803== in use at exit: 20 bytes in 1 blocks
==28803== total heap usage: 1 allocs, 0 frees, 20 bytes allocated
==28803==
==28803== LEAK SUMMARY:
==28803== definitely lost: 0 bytes in 0 blocks
==28803== indirectly lost: 0 bytes in 0 blocks
==28803== possibly lost: 0 bytes in 0 blocks
==28803== still reachable: 20 bytes in 1 blocks
==28803== suppressed: 0 bytes in 0 blocks
==28803== Rerun with --leak-check=full to see details of leaked memory
==28803==
==28803== For counts of detected and suppressed errors, rerun with: -v
==28803== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 13 from 6)
My question is, Is this a programming error, or rather a bug in dlfcn/libdl.so?
Looks like the latter. However this does not appear to be a big deal because if you repeat the dlopen/dlsym/dlclose calling another routine you'll see that the memory leak is of the same size, it does not grow with the number of dlopen/dlclose calls.