new libstdc++ of gcc5.1 may allocate large heap memory - c++

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.

Related

Why is valgrind reporting two memory allocations when my code only requests one?

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.

valgrind leaks detected no matter what

Even when I compile and run a program like this:
int main() {
return 0;
}
I get the following valgrind errors when I run valgrind --leak-check=yes ./a.out
==26391== LEAK SUMMARY:
==26391== definitely lost: 0 bytes in 0 blocks
==26391== indirectly lost: 0 bytes in 0 blocks
==26391== possibly lost: 72 bytes in 3 blocks
==26391== still reachable: 200 bytes in 6 blocks
==26391== suppressed: 18,528 bytes in 153 blocks
==26391== Reachable blocks (those to which a pointer was found) are not shown.
==26391== To see them, rerun with: --leak-check=full --show-leak-kinds=all
I am compiling with clang++ test.cpp. I am at a total loss for how to fix this.
Thank you!
Valgrind manual has the following about possibly lost
This means that a chain of one or more pointers to the block has been
found, but at least one of the pointers is an interior-pointer. This
could just be a random value in memory that happens to point into a
block, and so you shouldn’t consider this ok unless you know you have
interior-pointers.
This implies that all reported possibly lost occurrence are not leak. This need to be confirmed by code perusal to check leak.
For your particular case, we know there is no leak happening in your code.
You might like to rerun valgrind again with --leak-check=full --show-leak-kinds=all

C++ empty program memory leak

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.

Summary of Valgrind : is there a memory leak in the output?

My program is written in C++, i ran valgrind to check for memory issues. However, i am not quite sure, what happens when you have more allocated memory than freed, yet the summary says there is no leak.
Here is the output of the following command:
valgrind --leak-check=full ./myprogram
The output (Centos 6):
==28196==
==28196== HEAP SUMMARY:
==28196== in use at exit: 66,748 bytes in 1 blocks
==28196== total heap usage: 7 allocs, 6 frees, 67,964 bytes allocated
==28196==
==28196== LEAK SUMMARY:
==28196== definitely lost: 0 bytes in 0 blocks
==28196== indirectly lost: 0 bytes in 0 blocks
==28196== possibly lost: 0 bytes in 0 blocks
==28196== still reachable: 66,748 bytes in 1 blocks
==28196== suppressed: 0 bytes in 0 blocks
==28196== Reachable blocks (those to which a pointer was found) are not shown.
==28196== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==28196==
==28196== For counts of detected and suppressed errors, rerun with: -v
==28196== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
Profiling timer expired
Can somebody elaborate on the suppression issue?
Thank you
Still reachable means that you have pointers to the memory but you didn't free it before shutdown. In most cases, this means that there isn't a problematic memory leak because most of the time this is a data structure you filled in but didn't free before shutdown.
This question
Still Reachable Leak detected by Valgrind has more explanation in the top answer.
EDIT: To elaborate on suppression, valgrind can read files to suppress certain errors, and this note that is suppressed 2 from 2 means that 2 errors from the list of suppressed errors were also found. Errors are often suppressed because they are in a third party library or are known to not cause issues. For more information about suppressing errors, please check valgrind's explanation of error suppression.

Valgrind: Where is my memory leak?

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.