-   Linux - Software (
-   -   How to fix libudev memory leaks (

dagbay 02-04-2018 03:29 AM

How to fix libudev memory leaks
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:

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");
/* 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);
/* 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, unref of all allocated objects and exit.
return 0;
devices = udev_enumerate_get_list_entry(enumerate);
/* For each item enumerated, print out its information.
The fiest line that leaks is:
udev_enumerate_add_match_subsystem(enumerate, "hidraw");
Here is valgind report:
==20471== HEAP SUMMARY:
==20471== in use at exit: 4,096 bytes in 1 blocks
==20471== total heap usage: 11 allocs, 10 frees, 28,086 bytes allocated
==20471== 4,096 bytes in 1 blocks are still reachable in loss record 1 of 1
==20471== at 0x482E27C: malloc (vg_replace_malloc.c:299)
==20471== by 0x48624DA: ??? (in /lib/i386-linux-gnu/
==20471== by 0x486A742: ??? (in /lib/i386-linux-gnu/
==20471== by 0x108BAA: main (in /home/pi/projects/eclipse/testUSB/udevHidraw)
==20471== LEAK SUMMARY:
==20471== definitely lost: 0 bytes in 0 blocks
==20471== indirectly lost: 0 bytes in 0 blocks
==20471== possibly lost: 0 bytes in 0 blocks
==20471== still reachable: 4,096 bytes in 1 blocks
==20471== suppressed: 0 bytes in 0 blocks
If the "leak debug block" is placed before that line valgrind is happy reporting no memory leaks.
The further down the example code that the "leak debug block" is moved the worse the memory leaks become.

This issue 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?

sundialsvcs 02-06-2018 08:03 AM

Well, if you have found a verifiable memory-leak, I'd say the first thing to do is to officially open a trouble-ticket. Attach your detailed findings to that ticket, and see what the developers say about it.

Also – if code really does need to run for a long time, a fairly standard technique is to arrange for the process to periodically "commit hari-kiri" and be immediately replaced by a new process. The operating system cleans up all the resources used by the old, dead one. This will compensate for any leaks although of course it won't cure them.

dagbay 02-06-2018 09:41 AM

Hi sundialsvcs,
I am Shocked to my bones that you suggest Hara Kiri. I understand that it is an effective stop gap.

All times are GMT -5. The time now is 10:42 PM.