Device.Net icon indicating copy to clipboard operation
Device.Net copied to clipboard

Unmanaged memory leak in WindowsHidApiService.GetHidCapabilities

Open VerusMaya opened this issue 4 years ago • 3 comments

Describe the issue I observed an ongoing unmanaged memory leak when regularly polling for connected devices. I reproduced it with a minimal CLI .exe and narrowed it down to WindowsHidApiService.GetHidCapabilities. To resolve the leak, change the HidD_FreePreparsedData pointerToPreparsedData parameter to not be ref.

The HidD_GetPreparsedData documentation shows a *PreparsedData parameter. This matches with the out parameter option used. https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/hidsdi/nf-hidsdi-hidd_getpreparseddata

The HidD_FreePreparsedData documentation shows a PreparsedData parameter with no dereference. I believe it should therefore be called without ref. https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/hidsdi/nf-hidsdi-hidd_freepreparseddata

Relevant call stack - WindowsHidApiService.GetHidCapabilities WindowsHidApiService.GetDeviceDefinition WindowsHidDeviceFactoryExtensions.GetDeviceDefinition WindowsDeviceEnumerator.GetConnectedDeviceDefinitionsAsync

Screenshots Memory profiler running for one minute. Notice the bottom-right section for unmanaged memory breakdown by module.

hid memory leak - 1m without fix

hid memory leak - 1m fixed with fix

Your Code The memory leak can be reproduced easily.

static async Task Main(string[] args) {
	IDeviceFactory factory = new FilterDeviceDefinition(0x1234, 0x5678).CreateWindowsHidDeviceFactory();
	while (true) {
		_ = await factory.GetConnectedDeviceDefinitionsAsync();
		await Task.Delay(TimeSpan.FromMilliseconds(100));
	}
}

The leak can be resolved with two changes. https://github.com/MelbourneDeveloper/Device.Net/blob/417330ef418a7bacce36dae29eb6f67fc7620723/src/Hid.Net/Windows/WindowsHidApiService.cs#L61

private static extern bool HidD_FreePreparsedData(IntPtr pointerToPreparsedData);

https://github.com/MelbourneDeveloper/Device.Net/blob/417330ef418a7bacce36dae29eb6f67fc7620723/src/Hid.Net/Windows/WindowsHidApiService.cs#L117

isSuccess = HidD_FreePreparsedData(pointerToPreParsedData);

Log / Stack Trace No relevant logging or stack trace.

Info

  • Platform: Windows 10
  • Device Type: HID
  • Version: 4.2.1
  • .NET: 5.0

PR coming soon.

VerusMaya avatar Aug 27 '21 06:08 VerusMaya

Following up since it has been a bit.

Have you had a chance to look into this?

It would be great to get an updated nuget package with the memory leak resolved.

Thank you!

VerusMaya avatar Oct 01 '21 19:10 VerusMaya

?

White-Rabbit-Scientific avatar Jul 29 '22 08:07 White-Rabbit-Scientific

Great work finding this. 💯 forked and fixed. until this gets merged into main branch.

HossamElwahsh avatar Mar 05 '23 19:03 HossamElwahsh