I am using valgrind to track memory errors. I've noticed that valgrind detects an uninitialized value error sometimes for the same code and test conditions. What could be the reason for the strange behavior?
Run1:
valgrind --leak-check=full --track-origins=yes ./parcob cobalt_tet map_tet
==14034== Use of uninitialised value of size 8
==14034== at 0x36936D5B20: profil_counter (in /lib64/libc-2.5.so)
==14034== by 0x36936302CF: ??? (in /lib64/libc-2.5.so)
==14034== by 0x369AE7290C: std::istream::operator>>(int&) (in /usr/lib64/libstdc++.so.6.0.8)
==14034== by 0x414C68: mesh::__FVMESH<int, double>::ReadCobaltMesh(char const*, char const*) (unsmesh_io.h:975)
==14034== by 0x419948: main (main.cpp:47)
==14034== Uninitialised value was created by a stack allocation
==14034== at 0x369AE4E3C0: ??? (in /usr/lib64/libstdc++.so.6.0.8)
==14034==
==14034==
==14034== HEAP SUMMARY:
==14034== in use at exit: 263,884 bytes in 1 blocks
==14034== total heap usage: 8,923 allocs, 8,922 frees, 495,130 bytes allocated
==14034==
==14034== LEAK SUMMARY:
==14034== definitely lost: 0 bytes in 0 blocks
==14034== indirectly lost: 0 bytes in 0 blocks
==14034== possibly lost: 0 bytes in 0 blocks
==14034== still reachable: 263,884 bytes in 1 blocks
==14034== suppressed: 0 bytes in 0 blocks
==14034== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 4 from 4)
Run2
valgrind --leak-check=full --track-origins=yes ./parcob cobalt_tet map_tet
==14035==
==14035== HEAP SUMMARY:
==14035== in use at exit: 263,884 bytes in 1 blocks
==14035== total heap usage: 8,923 allocs, 8,922 frees, 495,130 bytes allocated
==14035==
==14035== LEAK SUMMARY:
==14035== definitely lost: 0 bytes in 0 blocks
==14035== indirectly lost: 0 bytes in 0 blocks
==14035== possibly lost: 0 bytes in 0 blocks
==14035== still reachable: 263,884 bytes in 1 blocks
==14035== suppressed: 0 bytes in 0 blocks
==14035== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 4 from 4)
Sorry for posting a verbose output.
NOTE: Application was compiled using Intel compiler suite
Related
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.
My valgrind is telling me that it found non-freed heap memory for the most trivial C++ code.
My code is shown as follows:
#include <iostream>
#include <string>
int main() {
std::cout << "Hello!!!!" << std::endl;
return 0;
}
And the result of valgrind is here:
==12455== HEAP SUMMARY:
==12455== in use at exit: 72,704 bytes in 1 blocks
==12455== total heap usage: 2 allocs, 1 frees, 73,728 bytes allocated
==12455==
==12455== 72,704 bytes in 1 blocks are still reachable in loss record 1 of 1
==12455== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==12455== by 0x4EC3EFF: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==12455== by 0x40106C9: call_init.part.0 (dl-init.c:72)
==12455== by 0x40107DA: call_init (dl-init.c:30)
==12455== by 0x40107DA: _dl_init (dl-init.c:120)
==12455== by 0x4000C69: ??? (in /lib/x86_64-linux-gnu/ld-2.23.so)
==12455==
==12455== LEAK SUMMARY:
==12455== definitely lost: 0 bytes in 0 blocks
==12455== indirectly lost: 0 bytes in 0 blocks
==12455== possibly lost: 0 bytes in 0 blocks
==12455== still reachable: 72,704 bytes in 1 blocks
==12455== suppressed: 0 bytes in 0 blocks
==12455==
==12455== For counts of detected and suppressed errors, rerun with: -v
==12455== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Is this a bug of valgrind?
This is due to the way the C++ standard library works. The containers allocate chunks of memory (called pools) and manage them internally. They use basically a memory manager of their own, rather than relying on system's memory manager. Therefore, when an object is destroyed, it's memory is freed by the internal allocator for reuse, but not given back to the operating system.
This is also described in valgrind's FAQ here.
To generalize a bit more, valgrind is a very useful tool, but you should not aim for 0 leaks, but rather to understand its reports and find leaks that indicate a problem in the code.
I use valgrind 3.14.0 under Ubuntu 19.04 and i dont get any detections. I ran with --leak-check=fulland without. Maybe its just some versions of valgrind.
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 have several tests that run and in the end I run Valgrind to verify my libraries memory usage. Valgrind consistently complains about:
==27022== HEAP SUMMARY:
==27022== in use at exit: 6,139 bytes in 3 blocks
==27022== total heap usage: 609 allocs, 606 frees, 19,877,073 bytes allocated
==27022==
==27022== 32 bytes in 1 blocks are still reachable in loss record 1 of 3
==27022== at 0x4A08121: calloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==27022== by 0x3A1A60168F: _dlerror_run (in /usr/lib64/libdl-2.17.so)
==27022== by 0x3A1A601197: dlsym (in /usr/lib64/libdl-2.17.so)
==27022== by 0x3A9D8A796D: ??? (in /usr/lib64/nvidia/libGL.so.331.67)
==27022== by 0x3A9DAE965F: ??? (in /usr/lib64/nvidia/libGL.so.331.67)
==27022== by 0x3A9DB1CB1F: ???
==27022== by 0x3A9D8CD36A: ??? (in /usr/lib64/nvidia/libGL.so.331.67)
==27022==
==27022== 83 bytes in 1 blocks are still reachable in loss record 2 of 3
==27022== at 0x4A06409: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==27022== by 0x3A1A2863F9: strdup (in /usr/lib64/libc-2.17.so)
==27022== by 0x3A9D8A964E: ??? (in /usr/lib64/nvidia/libGL.so.331.67)
==27022== by 0x6578652F32322F: ???
==27022==
==27022== 6,024 bytes in 1 blocks are definitely lost in loss record 3 of 3
==27022== at 0x4A08121: calloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==27022== by 0x3A9D8C032E: ??? (in /usr/lib64/nvidia/libGL.so.331.67)
==27022==
==27022== LEAK SUMMARY:
==27022== definitely lost: 6,024 bytes in 1 blocks
==27022== indirectly lost: 0 bytes in 0 blocks
==27022== possibly lost: 0 bytes in 0 blocks
==27022== still reachable: 115 bytes in 2 blocks
==27022== suppressed: 0 bytes in 0 blocks
These do not seem to be related to my library. Should I be concerned about theses warnings?
Or should I be making an attempt to suppress these leaks? If I should suppress what would be the cleanest way to do this from a Makefile?
It is hard to say whether you should suppress them or not, but if you are certain that your library is clean, you can generate a suppression file.
You can then call Valgrind with the "--suppressions" flag. If the name of your suppression file is suppfile:
> valgrind --suppressions=suppfile ./program
If you are executing valgrind from a Makefile, add the suppressions flag to the valgrind command. You can also create a default options file ".valgrindrc", which you put in the same directory as your Makefile. In this file, put any arguments you want.