Skip to content

Windows: driver host process crashes ~1s after DualSense virtual gamepad creation; all libvirtualhid devices become invalid until reboot #199

Open

Description

@Bar-bs

Describe the Bug

Environment

  • OS: Windows 10 Pro 22H2 (build 19045.6466)
  • Sunshine: 2026.914.233613 (commit 63d35f702ee9e362e43263742981836ec0710384)
  • libvirtualhid Windows driver: 2026.914.1218.10 (active license)
  • GPU: NVIDIA GeForce RTX 5060
  • gamepad_driver: all (first occurrence), then virtualhid
  • Virtual gamepad: DualSense, auto-selected by client-reported type
  • Client: Moonlight for Windows 6.2.0
  • Physical controller: Sony DualSense (CFI-ZCT1W)

Description

About 1 second after Sunshine creates the virtual DualSense gamepad, the device driver host process terminates. From that moment every libvirtualhid device (gamepad, mouse, keyboard) fails with "invalid handle", the virtual controller disconnects from the session and Sunshine becomes unstable / crashes. It also happens when the controller is disconnected on the client side.

Log excerpt (Italian Windows, translated):
[16:44:21.951] Info: Gamepad 0 will be Sunshine (libvirtualhid) PS5 Controller
[16:44:22.861] Warning: submit libvirtualhid gamepad state: submit Windows input report: The process hosting the driver for this device has been terminated.
[16:44:22.861] Warning: submit libvirtualhid gamepad gyroscope: submit Windows input report: Invalid handle.
[16:44:22.861] Warning: submit libvirtualhid gamepad acceleration: submit Windows input report: Invalid handle.
(~48,000 similar warnings in 6 minutes, mostly gyroscope/acceleration, then mouse/keyboard/scroll)
[16:48:54.166] Warning: create libvirtualhid gamepad: create Windows virtual HID device: Invalid handle.
[16:48:54.167] Info: Gamepad 0 will be DualShock 4 controller (fallback to ViGEmBus)

After restarting Sunshine with gamepad_driver = virtualhid, the driver is reported as "Virtual HID Driver is selected but is unavailable or unlicensed" and all gamepad types are disabled, even though the license is active. Only a reboot restores the driver. The following Sunshine start reports "nvprefs: Opened undo file from previous improper termination".

Steps to reproduce

  1. Windows host with libvirtualhid 2026.914.1218.10, gamepad_driver = all or virtualhid
  2. Connect from Moonlight (Windows 6.2.0) with a DualSense, so the DualSense type is auto-selected
  3. Use the controller, or disconnect it during the session
  4. The driver host process terminates shortly after

Attachments

sunshine.log.5 (crash at 16:44), sunshine.log.4 (driver unavailable after restart)

Expected Behavior

The virtual gamepad is created and removed without crashing the driver host. If the host does crash, the driver recovers without a reboot and is not reported as unlicensed.

sunshine4.log
sunshine5.log

Additional Context

No response

Activity

  1. Bar-bs commented on Oct 20, 2026

    @Bar-bs
    Author

    WUDFHost.exe crash events from Event Viewer (Application log). The driver host crashes with heap corruption; the 16:44:22 crash matches the Sunshine log timestamp exactly.

    Faulting application: WUDFHost.exe, version 10.0.19041.6093
    Faulting module: ntdll.dll, version 10.0.19041.6456
    Exception code: 0xc0000374 (STATUS_HEAP_CORRUPTION)
    Fault offset: 0x00000000000ff489

    Occurrences:

    • 2026-10-20 16:40:45 (PID 0x444), WER report c7ee1bd8-198d-4c45-9ee9-ce098aec6bc3
    • 2026-10-20 16:44:22 (PID 0x418), WER report df4ced52-fe75-4d18-b944-c4ce1e5512df

    WER buckets: PCH_B9_FROM_ntdll+0x9E0F4 / PCH_65_FROM_ntdll+0x9E0F4

    Crash dumps are available in the WER ReportQueue; I can share them privately if useful.

    wudfhost_crash.txt

  2. ReenigneArcher commented on Oct 20, 2026

    @ReenigneArcher
    Member

    This appears to be the same defect as #196: both reports show virtual DualSense creation/removal followed by WUDFHost.exe heap corruption (0xc0000374) and invalid handles across all libvirtualhid devices. Your log places the first driver-host failure 910 ms after controller creation. The later "unavailable or unlicensed" message does not establish a license problem.

    #196's heap excerpt contains our DualSense firmware-report payload, making feature-report handling a useful lead, but the corrupting operation is not confirmed.

    Local testing on Windows 11 build 26300 with driver 2026.1013.1243.17 did not reproduce it: 61 focused tests, repeated native consumer tests, 20 lifecycle cycles with 61,200 input submissions and concurrent feature reads/feedback, and three abrupt client exits passed.

    Please share one of the offered raw WUDFHost.exe crash dumps (.dmp), privately if preferred, together with its matching Report.wer and %WINDIR%\Temp\libvirtualhid-umdf-driver.log. The Event Viewer output confirms corruption, but the dump is needed to inspect the damaged allocation and call stacks.

  3. Bar-bs commented on Oct 20, 2026

    @Bar-bs
    Author

    Here are the files you asked for, from a new crash at 21:26:19Z (same pattern):

    • Raw dump: WUDFHost.exe.1156.dmp (~24 MB, LocalDumps DumpType 2). It contains process memory, so I'd rather send it privately. Let me know where.
    • Report.wer and driver log: attached in libvirtualhid-199_github.zip:
    File Content
    libvirtualhid-umdf-driver.log %WINDIR%\Temp\libvirtualhid-umdf-driver.log, covering all crashes below
    Report_20261020_212619Z.wer crash in the dump, in VhfDelete (StackHash_b405)
    Report_20261020_160743Z.wer crash in VhfDelete (StackHash_b405)
    Report_20261020_144045Z.wer crash in VhfDelete (StackHash_b405)
    Report_20261020_144422Z.wer crash right after DualSense create_device success (StackHash_7679)
    Report_20261020_150911Z.wer crash with no driver activity logged since the last create_device success at 15:00:44Z (StackHash_9290)

    All five are WUDFHost.exe 10.0.19041.6093, exception c0000374 in ntdll 10.0.19041.6456. The .wer files are the Report.wer files from the AppCrash_WUDFHost.exe_* folders, renamed by crash time (UTC).

    Driver log (times UTC)

    21:26:19Z – the crash in the dump (dump written at 21:26:20Z)

    21:26:03.557Z create_device success
    21:26:19.174Z destroy_device found
    21:26:19.174Z delete_vhf_device begin
    21:26:19.175Z delete_vhf_device VhfDelete status=0x00000000
    21:30:23.488Z DriverEntry begin        <- host restarted
    

    14:40:45Z – same as above: the host dies right after VhfDelete, and WdfObjectDelete target is never logged.

    14:44:21Z – no teardown in that host process

    14:44:21.951Z create_device begin
    14:44:21.953Z create_device success   (DualSense)
    14:53:38.987Z DriverEntry begin        <- nothing in between
    

    What I could see in the dump (no PDB, stack reconstructed from return addresses)

    WUDFx02000
     -> libvirtualhid_umdf+0xe3aa    (IOCTL dispatch -> destroy_device)
     -> libvirtualhid_umdf+0x13fb9   (delete_vhf_device -> VhfDelete)
     -> VhfUm+0x205d ... +0x5aee     call free
     -> msvcrt+0x19c9c               call RtlFreeHeap
     -> ntdll: 0xc0000374
    
    • The failure is detected when VhfDelete frees one of VhfUm's own heap blocks. That block's header, and the tail of the block before it, are overwritten with small 16-bit values (14 00 … 24 00 00 40 3c 00 01 00 0a 00 02 00 06 00), which looks like an earlier overrun. Nearby blocks carry the VhfA tag.
    • The DualSense firmware payload (20 4a 75 6c …) is not on the heap in this dump. It only appears in the DLL's read-only data.

    From the source (libvirtualhid_umdf.cpp, unchanged since v2026.914.1218.10)

    • The feature, input and output copies into VHF buffers are all bounds-checked, so I couldn't find a direct overflow from the driver.
    • The DualSense BT descriptor declares output reports 0x32–0x39 up to 547 bytes, while LVH_WINDOWS_MAX_OUTPUT_REPORT_SIZE is 256. This might be related, since VhfUm sizes its state from the descriptor.

    My setup is Windows 10 22H2 (19045) with Steam running.

    libvirtualhid-199_github.zip

  4. ReenigneArcher commented on Oct 20, 2026

    @ReenigneArcher
    Member

    Thanks for collecting these files and the dump analysis. Please upload WUDFHost.exe.1156.dmp to Google Drive and share it with redacted, granting viewer access with downloading allowed. Keep access restricted to that address, and reply here once it has been shared.

    I also checked the exact libvirtualhid revision bundled with your Sunshine build: the Windows backend converts DualSense profiles to USB before creation, using a descriptor with 48-byte output reports. The oversized Bluetooth reports should therefore not be involved in the normal creation path. The raw dump will let us inspect the damaged VHF allocation and call stacks directly.

  5. Bar-bs commented on Oct 21, 2026

    @Bar-bs
    Author

    Done, WUDFHost.exe.1156.dmp (zipped) is shared with redacted on Google Drive, viewer access with download allowed, restricted to that address.

    Thanks for the correction on the descriptor. With the profile converted to USB (48-byte output reports), the 547-byte Bluetooth output reports aren't in play, so please disregard that point.

    Let me know if you need another dump, e.g. with full page heap enabled on WUDFHost.exe, or a run with Steam closed.

  6. ReenigneArcher commented on Oct 21, 2026

    @ReenigneArcher
    Member

    Thanks—the private dump confirms corruption immediately after a 64-byte VHF report buffer, detected during VhfDelete. Please capture one reproduction with full PageHeap, which should catch the invalid access earlier.

    1. Use the existing driver and keep your existing LocalDumps DumpType=2 configuration. If GFlags is missing, install Debugging Tools for Windows from the Windows SDK (Microsoft documentation).

    2. Open Command Prompt as administrator and run:

      "%ProgramFiles(x86)%\Windows Kits\10\Debuggers\x64\gflags.exe" /p /enable WUDFHost.exe /full
      "%ProgramFiles(x86)%\Windows Kits\10\Debuggers\x64\gflags.exe" /p

      Confirm WUDFHost.exe is listed with full traces, then reboot so the driver host starts with PageHeap enabled.

    3. Reproduce the same DualSense scenario, initially keeping Steam in the same state as before. The crash may occur earlier. Collect the newly generated full .dmp from your configured LocalDumps folder, the matching Report.wer if available, and %WINDIR%Templibvirtualhid-umdf-driver.log.

    Disable PageHeap afterward, even if it does not reproduce: run these in an administrator Command Prompt, then reboot again:

    "%ProgramFiles(x86)%\Windows Kits\10\Debuggers\x64\gflags.exe" /p /disable WUDFHost.exe
    "%ProgramFiles(x86)%\Windows Kits\10\Debuggers\x64\gflags.exe" /p

    Confirm WUDFHost.exe is no longer listed. This setting affects all WUDFHost instances and increases memory usage; rebooting alone does not disable it (PageHeap reference).

    Please ZIP the new dump and share it privately through the same restricted Google Drive arrangement as before, with Viewer access and downloading allowed. Keep the dump/link off the public issue and reply here once it is shared.

  7. Bar-bs commented on Oct 21, 2026

    @Bar-bs
    Author

    Reproduced with full PageHeap on WUDFHost.exe (GFlags /p /enable WUDFHost.exe /full, rebooted, same DualSense scenario, Steam in the same state).

    With PageHeap the host no longer fails with c0000374 in VhfDelete. It now stops at the bad write itself, about 1 s after the DualSense is created:

    17:31:35.513Z create_device success   (DualSense)
    17:31:36Z     WUDFHost.exe terminated (WER event: WUDFUnhandledException)
    

    LocalDumps didn't fire because UMDF handled the exception itself. The dump is the one UMDF wrote to %ProgramData%\Microsoft\WDF\WudfHost_ext__1056.dmp (minidump, ~200 KB). I've shared it privately with lizardbytedev@gmail.com on Google Drive the same way as before (libvirtualhid-199_pageheap_dump_PRIVATE.zip, together with the driver log).

    Note: the dump analysis below was done with Claude (Anthropic's AI assistant). It parsed the minidump directly, without WinDbg or a PDB, so please double-check it against the dump with symbols.

    What it found (offsets only, against v2026.914.1218.10):

    • Exception c0000005, write to 0x1d0f2217000, which is the PageHeap guard page.
    • RIP libvirtualhid_umdf+0x3049d, inside an AVX memset loop. Caller libvirtualhid_umdf+0x127ea, called from the VhfUm worker thread (VhfUm+0x31de, thread entry VhfUm+0x47c9), so this is a VHF async callback.
    • At r14 there's the HID_XFER_PACKET passed to the callback:
      reportBuffer = 0x1d0f2216fc0, reportBufferLen = 0x80 (128), reportId = 0x09.
    • The buffer starts 64 bytes before the guard page, so the real allocation is 64 bytes while reportBufferLen says 128. The memset (rax = buffer start, 0x80 bytes total) runs past the end of the 64-byte buffer. That matches what you found in the first dump.

    Report ID 0x09 is the DualSense pairing feature report, so this looks like LvhEvtVhfGetFeature → copy_vhf_feature_report. The size check passes (20 ≤ 128), and then

    std::fill_n(packet.reportBuffer, packet.reportBufferLen, UCHAR {});

    zero-fills 128 bytes into a 64-byte buffer. copy_vhf_input_report has the same fill_n(..., reportBufferLen) pattern. That would also explain the "zeroed" heap block in #196.

    I don't know why VHF reports 128 for a 64-byte buffer on this system (Windows 10 19045, VhfUm 10.0.19041). It may be the requester's buffer size rather than VhfUm's copy. But writing only report->size() bytes instead of filling the whole reportBufferLen should avoid the overrun either way.

  8. ReenigneArcher commented on Oct 21, 2026

    @ReenigneArcher
    Member

    I believe this is fixed in the above mentioned PR. Could you please test the driver from https://github.com/LizardByte/libvirtualhid/actions/runs/39655021413/attempts/1?pr=200#artifacts to see if it solves the issues for you?

  9. Bar-bs commented on Oct 22, 2026

    @Bar-bs
    Author

    Tested the driver from the PR #200 build (0.0.200.0, run 39655021413) on the same Windows 10 22H2 (19045) machine, same DualSense setup with Steam running. Several controller create/remove cycles so far and no WUDFHost crash: no unexpected DriverEntry restarts in the driver log and no UMDF host-termination events. Looks fixed on my side. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions