I searched around but there seems no answers for me so I decided to ask here. So I used valgrind to check my program,here is the result
==24810== HEAP SUMMARY:
==24810== in use at exit: 1,478 bytes in 30 blocks
==24810== total heap usage: 50 allocs, 20 frees, 43078 bytes allocated
==24810==
==24810== LEAK SUMMARY:
==24810== definitely lost: 0 bytes in 0 blocks
==24810== indirectly lost: 0 bytes in 0 blocks
==24810== possibly lost: 0 bytes in 0 blocks
==24810== still reachable: 1,478 bytes in 30 blocks
==24810== suppressed: 0 bytes in 0 blocks
Is that a leak?
If so, what could be the reason?
It isn't a true leak in that the 30 extra chunks that were allocated are still reachable. It appears that you failed to free some structures at the end of your program's run. Note that the run time libraries will sometimes leave a few allocated objects around at the end but this doesn't feel like one of those cases.
Not a leak, it just means that some blocks of memory are still reachable at termination. To look for true memory leaks look at "definitely lost" and "indirectly lost"
See this post: Still Reachable Leak detected by Valgrind
Related
I am developing a C ++ application that reads inputs and acts on some
engines, sending information to another device.
The main program remains in an infinite loop repeating the same process every
5 seconds.
I am analyzing said application with Valgrind and it shows the following results:
==4453== 120 bytes in 1 blocks are still reachable in loss record 6 of 8
. . .
==4453== 106 byt4es in 1 blocks are possibly lost in loss record 7 of 8
. . .
==4453== LEAK SUMMARY:
==4453== definitely lost: 0 bytes in 0 blocks
==4453== indirectly lost: 0 bytes in 0 blocks
==4453== possibly lost: 148 bytes in 2 blocks
==4453== still reachable: 2,310 bytes in 8 blocks
==4453== suppressed: 0 bytes in 0 blocks
If I let the number of iterations the program performs in the infinite loop increase, the number of bytes in the "possibly lost" category remains the same, but the number of bytes in the "still reachable" category increases proportionally to the number of iterations performed (each time the program repeats the instructions contained in the loop, the number of still reachable bytes increases).
I have the following questions regarding this:
Are the bytes in the still reachable category really memory leaks?
Would it be permissible for the number of still reachable bytes to increase with the time the program is running or should this be solved?
Yes the "still reachable" bytes are memory leaks.
If your program runs constantly eventually the system will run out of memory and crash.
It should be solved.
It should be solved because of the eventual crash.
Alternatively in very complicated programs people have just given up, and they put in monitoring or a timer and just restart the program every hour. This is silly, but sometimes a stupid solution is the cheapest fastest one. Cheap, fast, good: pick two.
Solving this should be trivial.
I wrote a memory leak program and ran it. Look a few lines down from the top where it says operator new[] and then main (leak-test.cpp:7). Valgrind pinpoints the allocation for you.
$ valgrind --track-origins=yes --leak-check=full --show-leak-kinds=all ./leak-test
==929671==
==929671== HEAP SUMMARY:
==929671== in use at exit: 8,000 bytes in 1 blocks
==929671== total heap usage: 3 allocs, 2 frees, 81,728 bytes allocated
==929671==
==929671== 8,000 bytes in 1 blocks are still reachable in loss record 1 of 1
==929671== at 0x4095504: operator new[](unsigned long) (vg_replace_malloc.c:431)
==929671== by 0x100009F7: main (leak-test.cpp:7)
==929671==
==929671== LEAK SUMMARY:
==929671== definitely lost: 0 bytes in 0 blocks
==929671== indirectly lost: 0 bytes in 0 blocks
==929671== possibly lost: 0 bytes in 0 blocks
==929671== still reachable: 8,000 bytes in 1 blocks
==929671== suppressed: 0 bytes in 0 blocks
==929671==
==929671== For lists of detected and suppressed errors, rerun with: -s
==929671== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
When I run the following program through valgrind (valgrind ./a.out --leak-check=yes):
int main() {
char* ptr = new char;
return 0;
}
the report contains this:
==103== error calling PR_SET_PTRACER, vgdb might block
==103==
==103== HEAP SUMMARY:
==103== in use at exit: 1 bytes in 1 blocks
==103== total heap usage: 2 allocs, 1 frees, 72,705 bytes allocated
==103==
==103== LEAK SUMMARY:
==103== definitely lost: 1 bytes in 1 blocks
==103== indirectly lost: 0 bytes in 0 blocks
==103== possibly lost: 0 bytes in 0 blocks
==103== still reachable: 0 bytes in 0 blocks
==103== suppressed: 0 bytes in 0 blocks
==103== Rerun with --leak-check=full to see details of leaked memory
What's the extra 72,704-byte allocation valgrind is reporting? It seems to be taken care of before the program is over, so I'm guessing it's something the compiler is doing. I'm using gcc on an Ubuntu subsystem in Windows 10.
Edit: The memory leak was intentional in this example, but I get similar messages about an extra allocation regardless of whether or not there's a leak.
As you surmise, the extra allocation is part of the runtime, and it is correctly cleaned up as you can see in Valgrind's output. Don't worry about it.
If you're asking specifically what it is, you'll have to read the C++ runtime library of your specific compiler and version (libc since you're using gcc). But again, it shouldn't concern you.
Consider the following code
int main(){
return 0;
}
I compiled it with g++ and passed the output to valgrind. The output is the following.
==11752== HEAP SUMMARY:
==11752== in use at exit: 72,704 bytes in 1 blocks
==11752== total heap usage: 1 allocs, 0 frees, 72,704 bytes allocated
==11752==
==11965== LEAK SUMMARY:
==11965== definitely lost: 0 bytes in 0 blocks
==11965== indirectly lost: 0 bytes in 0 blocks
==11965== possibly lost: 0 bytes in 0 blocks
==11965== still reachable: 72,704 bytes in 1 blocks
==11965== suppressed: 0 bytes in 0 blocks
However, compiling the same code in C with gcc produces this valgrind output:
==11771== HEAP SUMMARY:
==11771== in use at exit: 0 bytes in 0 blocks
==11771== total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==11771==
==11771== All heap blocks were freed -- no leaks are possible
It looks like compiling
It looks like the empty C++ program actually allocates memory and does not free it (it's not a disaster since it's a "still reachable" leak), and I have no clue why this is happening.
I did this test on linux (solus os) with g++ 6.3.
Can someone explain what's going on ?
it's not a disaster since it's a "still reachable" leak
It's not even a leak. It is extremely common for programs to not free a block of memory that some global points to; doing the freeing is
unnecessary work that just makes the program exit slower
may cause complications if multiple threads are running (exiting thread may yank carpet from under the other thread)
may cause complications if other parts of cleanup can access this block, etc. etc.
I have no clue why this is happening.
To get a clue, run valgrind --leak-check=full --show-reachable=yes .... That will tell you where the block was allocated.
valgrind detects "still reachable leak" in an empty program compiled with gcc5.1, g++ ./a.cpp,
int main () {}
valgrind says, valgrind ./a.out,
==32037== HEAP SUMMARY:
==32037== in use at exit: 72,704 bytes in 1 blocks
==32037== total heap usage: 1 allocs, 0 frees, 72,704 bytes allocated
==32037==
==32037== LEAK SUMMARY:
==32037== definitely lost: 0 bytes in 0 blocks
==32037== indirectly lost: 0 bytes in 0 blocks
==32037== possibly lost: 0 bytes in 0 blocks
==32037== still reachable: 72,704 bytes in 1 blocks
==32037== suppressed: 0 bytes in 0 blocks
==32037== Rerun with --leak-check=full to see details of leaked memory
==32037==
==32037== For counts of detected and suppressed errors, rerun with: -v
==32037== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 5 from 5)
For c programs, valgrinds reports no memory leaks and no memory allocation.
In addition, for gcc5.0 and gcc4.9.2, valgrinds reports no memory leaks and no memory allocation too.
Then, I guess that new libstdc++ of gcc5.1 is the cause.
My question is how to reduce this huge memory allocation which may be in libstdc++.
Indeed, the execution time of this empty c++ program compiled with -O3 is larger than one of the empty c program by a few milliseconds (without systime).
The space is allocated as an emergency exception buffer in libsup++
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64535
the devs talk of maybe suppressing the trace in Valgrind but presumably nothing was done in the end. The only way of eliminating it from the trace right now would probably be to disable exceptions, but it doesn't look like it's a big deal either way, it's not as if the memory can be reclaimed for something else before the program exits.
I am working on a rather chaotic library (client/server application) which has a memory leak somewhere, but I cannot find where.
When I start the library and let it do its work, I get the following memory usage using top when it finished:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
21010 root 20 0 111m 12m 6836 S 0.0 0.7 0:29.20 myapp
21008 root 20 0 172m 99m 6480 S 0.0 5.8 0:14.39 myapp
The first line is the client, the second the server.
I let valgrind execute the server and got the following result:
==20904==
==20904== HEAP SUMMARY:
==20904== in use at exit: 4,723,124 bytes in 199 blocks
==20904== total heap usage: 40,423,345 allocs, 40,423,146 frees, 1,977,998,844 bytes allocated
==20904==
==20904== LEAK SUMMARY:
==20904== definitely lost: 0 bytes in 0 blocks
==20904== indirectly lost: 0 bytes in 0 blocks
==20904== possibly lost: 914 bytes in 18 blocks
==20904== still reachable: 4,722,210 bytes in 181 blocks
==20904== suppressed: 0 bytes in 0 blocks
==20904== Rerun with --leak-check=full to see details of leaked memory
==20904==
==20904== For counts of detected and suppressed errors, rerun with: -v
==20904== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2) Killed
If I understand this correctly, valgrind says that the server has just about 4,7M of memory still allocated with no real leaks.
It can be that there are no "real" leaks, but normally the library should at this state have freed all resources. I cannot see any part in the code where something is not freed.
How can I find out where the resources are still allocated?
You could use a brute-force method and print to a log file before each allocation and after each delete.
You may want to print the object's size (or the size allocated) and maybe the name of the object.
You are looking for matching pairs, allocation and deallocation.
You may also want to print out the invocation number which will help match, i.e. if there are 4 invocations of allocation, you should be able to find deallocation #3 to match with allocation #3.
This requires careful inspection of the code to verify that all allocations have been identified.