Hi, The attached patch fixes a bug in the udev_enumerate_get_list_entry() function of "libudev-enumerate.c". The move_later_prefix variable was reset to zero on each loop iteration, and thus the move_later entry (if any) was not added right after changing to another syspath prefix, but rather after exiting the enumeration loop. So this patch makes the sound card control node be added asap (after other nodes from the same sound card) rather than last (after all other nodes), which is probably a good thing, and obviously seems to be the original intent of this code. On my system, under some circumstances, it has the additional benefice to avoid an "udevadm trigger" segfault. What was happening was that, at some point in the loop iteration (a few tens of iterations after it was set), the move_later->syspath was becoming NULL, and thus the final udev_list_entry_add() was failing. I absolutly don't know why it was becoming NULL though, I've just seen it happening each time I have both my mouse and keyboard plugged on the monitor USB hub (go figure...). If this phenomena is of any interest, I can provide some printf-powered traces showing it. I'm not subscribed to the list, so please keep my address in replies. Thanks, Thomas de Grenier de Latour.
diff --git a/libudev/libudev-enumerate.c b/libudev/libudev-enumerate.c index 53cd53b..605c246 100644 --- a/libudev/libudev-enumerate.c +++ b/libudev/libudev-enumerate.c @@ -251,6 +251,7 @@ struct udev_list_entry *udev_enumerate_get_list_entry(struct udev_enumerate *ude unsigned int i; unsigned int max; struct syspath *prev = NULL, *move_later = NULL; + size_t move_later_prefix; udev_list_cleanup_entries(udev_enumerate->udev, &udev_enumerate->devices_list); qsort(udev_enumerate->devices, udev_enumerate->devices_cur, sizeof(struct syspath), syspath_cmp); @@ -258,7 +259,6 @@ struct udev_list_entry *udev_enumerate_get_list_entry(struct udev_enumerate *ude max = udev_enumerate->devices_cur; for (i = 0; i < max; i++) { struct syspath *entry = &udev_enumerate->devices[i]; - size_t move_later_prefix = 0; /* skip duplicated entries */ if (prev != NULL &&