add better windows error handling #388
No reviewers
Labels
No labels
3rdparty
Android
API
Author does not respond
bsd
bug
build system/CI
ci-virtual-device
CMake
Contributions Welcome
Core
dependencies
device-specific
documentation
don't_merge
duplicate
enhancement
Example
Haiku
hidraw
hotplug
info required
invalid
libusb
macOS
Misc
Not an issue
question
Release
Test
Test GUI
Windows
wontfix
No milestone
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
gh-libusb/hidapi!388
Loading…
Reference in a new issue
No description provided.
Delete branch "windows_error_improvements"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Oops, accidentally launched this PR before I intended. This PR merges the Windows messaging with what's already done in the Windows side of the library so that we can get better error reporting.
Regarding global error:
From the
hid_errordocumentation:The only backend that tries to implement this correctly is
hidraw.Nevertheless it has an issue too (a memory leak under some conditions).
While I understand your best inentions of preparing this PR, I'd rather want to accept an implementation that strictly follows all requirements as per documentation: uses a thread-local storage of some kind, and correctly releases all the error strings when not required anymore.
Or we need to change initial requirement, to make it easier to implement.
I don't see a perfect solution as of yet.
The device error improvement I'll gladly accept.
Hmm, yeah, that makes sense. I'll alter the PR to remove the global error handling.
I noticed when I tried adding the device error to the windows error that there was some heap corruption on freeing the memory via
LocalFree()infree_hid_device(). I couldn't tell if it was introduced by me or the heap corruption was happening somewhere else and my changes exposed it somehow. I debugged in Visual Studios and traced theLocalFree()s on the error string storage and didn't see any double frees anywhere.We've been having issues with a downstream library (
hidapi-rs) where after a HID device reset, everything crashes. We have that library pinned to a certain version which seems to use hidapi 0.11.0 (0ec60c0).Anyway, I'll remove the global error handling, do some more testing, and push the changes to this PR.
Alright, removed global error messaging. I also had to switch the device specific error message to
callocandfreesince the Win32LocalAllocandLocalFreewere doing some heap corruption (even though it's supposed to be thread local).I see two general issues with this implementation:
No early return in case if
dev == NULL; if it is NULL (for whatever reason) - we would silently get a memory leak;Double memory allocation (I guess no need to explain);
More comments regarding 2) :
Would be be willing to perform some additional refactoring?
I.e.: get rid of
FORMAT_MESSAGE_ALLOCATE_BUFFERto use preallocated memory in the first place, anduseFORMAT_MESSAGE_ARGUMENT_ARRAYto make the formatting.UPD: ok, after checking the doc, I see that we need
FORMAT_MESSAGE_FROM_SYSTEMto have string representation of the rror code so theFORMAT_MESSAGE_FROM_STRINGisn't a viable option, but still, callingFormatMessageWtwo times without theFORMAT_MESSAGE_ALLOCATE_BUFFERflag is enough to do both: concatenate theop/"error code message" and avoid double memory allocation.@ -233,3 +243,3 @@NULL,GetLastError(),error_code,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),Does the cocumentation of
FormatMessageWguarantees that the message will end with\r\n?I don't like this approach (nor the previous one).
Technically correct would be:
Yes, these are good recommendations.
The usage of these wide chars makes the concatenation annoying (can't just
strcpyto theFormatMessageWbuffer). Also,FormatMessageWrequires a real buffer to write to in order to return the error string length. Seems I'm going to have to tinker with this more to get it right.I believe we can easily and safely replace the type for
opto beconst wchar_t*.That was a surprise for me. Most WinAPI functions allow passing NULL for buffer to get the required buffer size.
I took liberty to update the implementation on my own