tests: Add tests/testcore.c, a multi-threaded stress test that hammers#1809
Open
sonatique wants to merge 2 commits into
Open
tests: Add tests/testcore.c, a multi-threaded stress test that hammers#1809sonatique wants to merge 2 commits into
sonatique wants to merge 2 commits into
Conversation
sonatique
force-pushed
the
testcore-program-from-PR-1795
branch
from
April 22, 2026 09:01
3a6cca4 to
1d05add
Compare
sonatique
added a commit
to sonatique/libusb
that referenced
this pull request
Apr 22, 2026
libusb_get_device_list / libusb_free_device_list from N threads in parallel. It exists primarily to reproduce the concurrent-enumeration crashes reported in libusb#1793 and the related set_composite_interface race surfaced during PR libusb#1795 review. The stressed code paths include: - usbi_get_device_by_session_id() - usbi_alloc_device() - usbi_connect_device() - libusb_unref_device() / ctx->usb_devs_lock - winusb_device_priv setup races in set_composite_interface and set_hid_interface (Windows, non-hotplug builds) The original C++20 reproducer was posted by smarvonohr and the C version with Win32 threads by mcuee in libusb#1795 (comment) This version is adapted from mcuee's C version, with two changes that make it portable and easier to build: - Use the same PLATFORM_POSIX / PLATFORM_WINDOWS thread abstraction that stress_mt.c uses (pthread_create on POSIX, _beginthreadex on Windows, CreateThread on Cygwin), instead of bare pthread. The original would not build with MSVC. - Print the device list once before starting the worker threads, so the operator can confirm at a glance which devices are present. This is useful because the bug only manifests when enumeration touches certain device shapes (e.g. composite devices with HID children that exercise set_composite_interface). Add msvc/testcore.vcxproj following the same template as msvc/stress_mt.vcxproj so the test builds out of the box in Visual Studio against libusb_static. Notes for runners: - The test only triggers the enumeration races in non-HOTPLUG builds. With Windows hotplug enabled, libusb_get_device_list is served from a cache and winusb_get_device_list never runs concurrently, so the bug does not manifest. - The default LOOPS = 100000 is intentionally large for the original bug-hunting use case but takes hours of real work even when the library is correct (each non-hotplug get_device_list does a full Windows USB enumeration, ~10-100 ms). Reduce LOOPS for a quick smoke test. - At least one composite USB device with HID-class child interfaces (USB game controller, headset with controls, Logitech Unifying receiver, etc.) must be present to exercise set_composite_interface. Pure UVC/UAC composite devices like webcams will NOT trigger that path because their child interfaces are not HID class and are not bound to any libusb-supported driver. Closes libusb#1808 Closes libusb#1809
Member
|
Two quick comments.
|
Member
|
For example, under macOS, without adding the new test to auto-tools build, it will not build testcore by default. Manual build: |
mcuee
reviewed
Apr 22, 2026
Member
It would be good to make number of threads and number of loops to be arguments to the test program. If we choose the default loops to be 100,000, we may want to inform the user the above info. |
seanm
reviewed
Apr 22, 2026
sonatique
added a commit
to sonatique/libusb
that referenced
this pull request
Jul 13, 2026
libusb_get_device_list / libusb_free_device_list from N threads in parallel. It exists primarily to reproduce the concurrent-enumeration crashes reported in libusb#1793 and the related set_composite_interface race surfaced during PR libusb#1795 review. The stressed code paths include: - usbi_get_device_by_session_id() - usbi_alloc_device() - usbi_connect_device() - libusb_unref_device() / ctx->usb_devs_lock - winusb_device_priv setup races in set_composite_interface and set_hid_interface (Windows, non-hotplug builds) The original C++20 reproducer was posted by smarvonohr and the C version with Win32 threads by mcuee in libusb#1795 (comment) This version is adapted from mcuee's C version, with two changes that make it portable and easier to build: - Use the same PLATFORM_POSIX / PLATFORM_WINDOWS thread abstraction that stress_mt.c uses (pthread_create on POSIX, _beginthreadex on Windows, CreateThread on Cygwin), instead of bare pthread. The original would not build with MSVC. - Print the device list once before starting the worker threads, so the operator can confirm at a glance which devices are present. This is useful because the bug only manifests when enumeration touches certain device shapes (e.g. composite devices with HID children that exercise set_composite_interface). Add msvc/testcore.vcxproj following the same template as msvc/stress_mt.vcxproj so the test builds out of the box in Visual Studio against libusb_static. Notes for runners: - The test only triggers the enumeration races in non-HOTPLUG builds. With Windows hotplug enabled, libusb_get_device_list is served from a cache and winusb_get_device_list never runs concurrently, so the bug does not manifest. - The default LOOPS = 100000 is intentionally large for the original bug-hunting use case but takes hours of real work even when the library is correct (each non-hotplug get_device_list does a full Windows USB enumeration, ~10-100 ms). Reduce LOOPS for a quick smoke test. - At least one composite USB device with HID-class child interfaces (USB game controller, headset with controls, Logitech Unifying receiver, etc.) must be present to exercise set_composite_interface. Pure UVC/UAC composite devices like webcams will NOT trigger that path because their child interfaces are not HID class and are not bound to any libusb-supported driver. Closes libusb#1808 Closes libusb#1809
sonatique
force-pushed
the
testcore-program-from-PR-1795
branch
from
July 13, 2026 10:05
1d05add to
7fc3b1c
Compare
Member
|
Looks good to me with the latest changes. |
libusb_get_device_list / libusb_free_device_list from N threads in parallel. It exists primarily to reproduce the concurrent-enumeration crashes reported in libusb#1793 and the related set_composite_interface race surfaced during PR libusb#1795 review. The stressed code paths include: - usbi_get_device_by_session_id() - usbi_alloc_device() - usbi_connect_device() - libusb_unref_device() / ctx->usb_devs_lock - winusb_device_priv setup races in set_composite_interface and set_hid_interface (Windows, non-hotplug builds) The original C++20 reproducer was posted by smarvonohr and the C version with Win32 threads by mcuee in libusb#1795 (comment) This version is adapted from mcuee's C version, with two changes that make it portable and easier to build: - Use the same PLATFORM_POSIX / PLATFORM_WINDOWS thread abstraction that stress_mt.c uses (pthread_create on POSIX, _beginthreadex on Windows, CreateThread on Cygwin), instead of bare pthread. The original would not build with MSVC. - Print the device list once before starting the worker threads, so the operator can confirm at a glance which devices are present. This is useful because the bug only manifests when enumeration touches certain device shapes (e.g. composite devices with HID children that exercise set_composite_interface). Add msvc/testcore.vcxproj following the same template as msvc/stress_mt.vcxproj so the test builds out of the box in Visual Studio against libusb_static. Notes for runners: - The test only triggers the enumeration races in non-HOTPLUG builds. With Windows hotplug enabled, libusb_get_device_list is served from a cache and winusb_get_device_list never runs concurrently, so the bug does not manifest. - The default LOOPS = 100000 is intentionally large for the original bug-hunting use case but takes hours of real work even when the library is correct (each non-hotplug get_device_list does a full Windows USB enumeration, ~10-100 ms). Reduce LOOPS for a quick smoke test. - At least one composite USB device with HID-class child interfaces (USB game controller, headset with controls, Logitech Unifying receiver, etc.) must be present to exercise set_composite_interface. Pure UVC/UAC composite devices like webcams will NOT trigger that path because their child interfaces are not HID class and are not bound to any libusb-supported driver. Closes libusb#1808 Closes libusb#1809
- Make thread and loop counts command-line arguments with -h/--help usage text, defaulting to 4 threads and 10000 loops so the test stays fast under 'make check', and warn in the usage text that large loop counts can run for hours on non-hotplug backends - Replace the THREADS/LOOPS #defines with typed static const defaults and allocate the per-thread arrays dynamically - Add a commented-out LIBUSB_OPTION_NO_DEVICE_DISCOVERY hint for exercising the Linux non-hotplug code path - Build testcore via autotools, mirroring stress_mt including the Emscripten PROXY_TO_PTHREAD link flags - Add testcore.vcxproj to the Visual Studio solution - Pass the initialized context to the initial device listing instead of NULL, and propagate worker failures to the exit code Note: will be squashed before merging the PR
sonatique
force-pushed
the
testcore-program-from-PR-1795
branch
from
July 14, 2026 13:23
7fc3b1c to
77241e3
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
libusb_get_device_list / libusb_free_device_list from N threads in parallel. It exists primarily to reproduce the concurrent-enumeration crashes reported in #1793 and the related set_composite_interface race surfaced during PR #1795 review.
The stressed code paths include:
Address issue: race in libusb get device list and libusb free device list with win usb backend + claim_interface race #1795 (comment) This version is adapted from mcuee's C version, with two changes that make it portable and easier to build:
Notes for runners:
Closes #1808