I wrote a socket server. And I realize when I hit Ctrl-C while it's running, there's some possible memory leak. I used valgrind to find this.
My server code is quite simple. Basically I create a Listener object, start a thread to accept connections and try to join that thread:
try {
Server::Listener listener(1234);
boost::thread l(boost::bind(&Server::Listener::start, &listener));
l.join();
} catch(exception& e) {
cout<<e.what()<<endl;
}
When I run valgrind, it give me:
==3580== Command: bin/Debug/p_rpc
==3580==
Listner started ...
in loop..
^C==3580==
==3580== HEAP SUMMARY:
==3580== in use at exit: 3,176 bytes in 24 blocks
==3580== total heap usage: 28 allocs, 4 frees, 4,328 bytes allocated
==3580==
==3580== 288 bytes in 1 blocks are possibly lost in loss record 21 of 24
==3580== at 0x4C29E46: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3580== by 0x4012084: _dl_allocate_tls (dl-tls.c:297)
==3580== by 0x4E3AABC: pthread_create##GLIBC_2.2.5 (allocatestack.c:571)
==3580== by 0x5260F9F: boost::thread::start_thread() (in /usr/lib/libboost_thread.so.1.49.0)
==3580== by 0x407B93: boost::thread::thread, boost::_bi::list1 > > >(boost::_bi::bind_t, boost::_bi::list1 > >&&) (thread.hpp:171)
==3580== by 0x404CA4: main (main.cpp:179)
==3580==
==3580== LEAK SUMMARY:
==3580== definitely lost: 0 bytes in 0 blocks
==3580== indirectly lost: 0 bytes in 0 blocks
==3580== possibly lost: 288 bytes in 1 blocks
==3580== still reachable: 2,888 bytes in 23 blocks
==3580== suppressed: 0 bytes in 0 blocks
==3580== Reachable blocks (those to which a pointer was found) are not shown.
==3580== To see them, rerun with: --leak-check=full --show-reachable=yes
==3580==
==3580== For counts of detected and suppressed errors, rerun with: -v
==3580== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 2 from 2)
Killed
It points out there's 288bytes possibly lost. I imagine I could use a signal handler to release this resourse. But I don't know how I do that. Can you give me an example please?
Cheers,
Elton
When a process closes, the OS automatically cleans up all memory owned by the process. You don't need to worry about freeing that memory when the program exits. The building is being demolished. Don't bother sweeping the floor and emptying the trash cans and erasing the whiteboards. And don't line up at the exit to the building so everybody can move their in/out magnet to out. All you're doing is making the demolition team wait for you to finish these pointless housecleaning tasks.
The kind of leaks you do need to worry about are those that continuously leak during the program's lifetime.
In principle, you can destroy the object there. There are restrictions on what you can do in a signal handler, and they mix very badly with threads. Note that in this area the compiler can do no (or very little) checking, the signal handler is just an ordinary function. Be extra careful.
The answers to this question give some details on how to do it.
Related
I'm working on a C++ application (an OpenSSL assignment for university), and I'm running it through valgrind, as one does. I've noticed some rather strange output when the program fails due to invalid input:
==1739== HEAP SUMMARY:
==1739== in use at exit: 588 bytes in 6 blocks
==1739== total heap usage: 52 allocs, 46 frees, 99,206 bytes allocated
==1739==
==1739== 44 bytes in 1 blocks are possibly lost in loss record 3 of 6
==1739== at 0x483BE63: operator new(unsigned long) (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==1739== by 0x4C20378: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.28)
==1739== by 0x4C03187: std::logic_error::logic_error(char const*) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.28)
==1739== by 0x4C0325C: std::invalid_argument::invalid_argument(char const*) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.28)
==1739== by 0x10FB6D: lab2::cryptoEngine::CBCCryptoEngine::encrypt() (CBCCryptoEngine.cpp:39)
==1739== by 0x10E355: main (main.cpp:135)
==1739==
==1739== 144 bytes in 1 blocks are possibly lost in loss record 4 of 6
==1739== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==1739== by 0x4BDB1F3: __cxa_allocate_exception (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.28)
==1739== by 0x10FB5B: lab2::cryptoEngine::CBCCryptoEngine::encrypt() (CBCCryptoEngine.cpp:39)
==1739== by 0x10E355: main (main.cpp:135)
==1739==
==1739== LEAK SUMMARY:
==1739== definitely lost: 0 bytes in 0 blocks
==1739== indirectly lost: 0 bytes in 0 blocks
==1739== possibly lost: 188 bytes in 2 blocks
==1739== still reachable: 400 bytes in 4 blocks
==1739== of which reachable via heuristic:
==1739== stdstring : 44 bytes in 1 blocks
==1739== suppressed: 0 bytes in 0 blocks
==1739== Reachable blocks (those to which a pointer was found) are not shown.
==1739== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==1739==
==1739== For lists of detected and suppressed errors, rerun with: -s
The code causing it is just a regular exception that is thrown when an input file is invalid. The exception is caught properly like this:
try {
engine.encrypt(bad_argument); // Placeholder. The exception type stands, though...
}
catch (const std::invalid_argument &e) {
std::cerr << "Exception while encrypting file: " << e.what() << std::endl;
delete (engine);
exit(EXIT_FAILURE);
}
I'm not 100% sure what it means, and if it is even a problem, since the memory will be reclaimed by the OS anyway. But I've never seen this kind of thing before, and wanted to check.
So, my question is, what is it caused by? Should I fix it? If so, how?
std::logic_error's constructor allocated memory for the "explanatory string". This is what() returns to you, in the exception handler (std::invalid_argument inherits from std::logic_error).
Observe that the backtrace shows the constructor overload that takes a const char * for a parameter. It would've been acceptable if that literal const char * got stashed away, and handed back to you from what(). However there are various immaterial reasons why the constructor is coded to make a copy of the "explanatory string" so that its contents are wholly owned by the constructed std::logic_error.
Your exception handler quietly called exit() and the process terminated. At which point valgrind notified you that the aforementioned allocated memory wasn't destroyed. This is true, that memory wasn't deallocated.
Had your exception handler's scope ended naturally (without calling exit()), std::logic_error's destructor would've deleted the allocated memory, and everyone would've lived happily ever after.
TLDR: this is only a technical memory leak. It is technically true only because the rug was pulled from under the process, by calling exit.
Note that valgrind said "possibly" instead of "definitely". There's no doubt that you have a memory leak when valgrind "definitely" claims one. If it's just "possibly", then there may or may not be a real memory leak.
exit loses more or less everything not recursively owned by objects of static storage duration. Of course this includes everything recursively owned by things on the stack, but also the active exception object (its memory is allocated in an unspecified way). In this particular case, you lose a buffer owned by a std::string owned by the active exception object.
If you care about such things, don't use exit in the middle of things. Rethrow the exception, catch it in main, let the handler finish, and then call exit (or just fall out of main naturally). You probably shouldn't, as this is not a real leak (i.e. there is no memory allocated and lost by the program while it is still running).
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.
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 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.