I'm implementing a libudev based monitoring code for USB devices under the hidraw driver. I've implemented the standard example from the web and checked for memory leaks with valgrind and gdb.
/*******************************************
libudev example.
This example prints out properties of
each of the hidraw devices. It then
creates a monitor which will report when
hidraw devices are connected or removed
from the system.
This code is meant to be a teaching
resource. It can be used for anyone for
any reason, including embedding into
a commercial product.
The document describing this file, and
updated versions can be found at:
http://www.signal11.us/oss/udev/
Alan Ott
Signal 11 Software
2010-05-22 - Initial Revision
2010-05-27 - Monitoring initializaion
moved to before enumeration.
*******************************************/
I was unhappy to find that some libudev functions that are not supposed to allocate memory are leaking. I traced this by exiting (after all objects are unreff'ed) at differrent points and looking at the valgrind report. Specifically This code leaks:
int main (void)
{
struct udev *udev;
struct udev_enumerate *enumerate;
struct udev_list_entry *devices, *dev_list_entry;
struct udev_device *dev, *devParent;
struct udev_monitor *mon;
int fd;
/* Create the udev object */
udev = udev_new();
if (!udev)
{
printf("Can't create udev\n");
exit(1);
}
/* This section sets up a monitor which will report events when
blah blah....
"hidraw" devices. */
/* Set up a monitor to monitor hidraw devices */
mon = udev_monitor_new_from_netlink(udev, "udev");
udev_monitor_filter_add_match_subsystem_devtype(mon, "hidraw", NULL);
udev_monitor_enable_receiving(mon);
/* Get the file descriptor (fd) for the monitor.
This fd will get passed to select() */
fd = udev_monitor_get_fd(mon);
/* Create a list of the devices in the 'hidraw' subsystem. */
enumerate = udev_enumerate_new(udev);
udev_enumerate_add_match_subsystem(enumerate, "hidraw");
if (1)
{
// leak debug block
udev_enumerate_unref(enumerate);
udev_monitor_unref(mon);
udev_unref(udev);
return 0;
}
udev_enumerate_scan_devices(enumerate);
devices = udev_enumerate_get_list_entry(enumerate);
/* For each item enumerated, print out its information.
Here is the valgrind output:
==11424== HEAP SUMMARY:
==11424== in use at exit: 4,096 bytes in 1 blocks
==11424== total heap usage: 11 allocs, 10 frees, 28,086 bytes allocated
==11424==
==11424== LEAK SUMMARY:
==11424== definitely lost: 0 bytes in 0 blocks
==11424== indirectly lost: 0 bytes in 0 blocks
==11424== possibly lost: 0 bytes in 0 blocks
==11424== still reachable: 4,096 bytes in 1 blocks
==11424== suppressed: 0 bytes in 0 blocks
==11424== Rerun with --leak-check=full to see details of leaked memory
If I place the "leak debug block" one line prior to its above position valgrind exits with a clean result of 0 bytes leaked.
If I advance the block one line down the code the next function increases the leak size and components:
==14262== in use at exit: 8,192 bytes in 2 blocks
==14262== total heap usage: 45 allocs, 43 frees, 150,907 bytes allocated
==14262==
==14262== LEAK SUMMARY:
==14262== definitely lost: 0 bytes in 0 blocks
==14262== indirectly lost: 0 bytes in 0 blocks
==14262== possibly lost: 0 bytes in 0 blocks
==14262== still reachable: 8,192 bytes in 2 blocks
==14262== suppressed: 0 bytes in 0 blocks
==14262== Rerun with --leak-check=full to see details of leaked memory
It gets worse after the next line and it is of concern because my code needs to run over years and such leaks can accumulate unchecked.
Any suggestions why it happens and how to keep it under control?
Seems that these memory leaks related to the hash tables as reported by valgrind are not a concern see discussion in
https://github.com/libratbag/libratbag/issues/405 and a relevant Red Hat bug report at https://bugzilla.redhat.com/show_bug.cgi?id=1280334.
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.
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
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.